您的位置:首页 > 大数据 > 人工智能

1020 Tree Traversals (25分)、1086 Tree Traversals Again (25分)、1102 Invert a Binary Tree (25分)练习二叉树的遍历

2020-02-29 18:28 477 查看

感觉给定两种遍历顺序求另一种遍历顺序时,只要在递归时把两个序列的起点终点细心搞明白就没有太大问题~~

1020 Tree Traversals (25分) 根据后序遍历,中序遍历求层序遍历

struct tNode
{
int data;
tNode* left;
tNode* right;
};

int postOrder[50];
int inOrder[50];

/**
begin1,end1代表某子树后续序列的起点与终点,begin2,end2代表某子树中序序列的起点与终点
*/
tNode* Create(int begin1, int end1, int begin2, int end2)
{
tNode* root = new tNode;
root->data = postOrder[end1];
int index;
for (int i = begin2; i <= end2; i++)
if (inOrder[i] == postOrder[end1])
index = i;
//左右子树节点个数
int leftNum = index - begin2;
int rightNum = end2 - index;
if (leftNum==0)
root->left = NULL;
else
root->left = Create(begin1, begin1 + leftNum - 1, begin2, index - 1);
if (rightNum==0)
root->right = NULL;
else
root->right = Create(begin1 + leftNum, end1 - 1, index + 1, end2);
return root;
}

void Level(tNode* root)
{
queue<tNode*> q;
q.push(root);
int flag = 0;
while (!q.empty())
{
tNode* t = q.front();
q.pop();
if (flag == 0) {
printf("%d", t->data);
flag = 1;
}
else
printf(" %d", t->data);
if (t->left != NULL)
q.push(t->left);
if (t->right != NULL)
q.push(t->right);
}
}

int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &postOrder[i]);
for (int i = 0; i < n; i++)
scanf("%d", &inOrder[i]);
tNode* root = Create(0, n - 1, 0, n - 1);
Level(root);
}

1086 Tree Traversals Again (25分) 已知先序遍历,中序遍历,求后续遍历

小技巧:
在后序遍历的递归过程中需要注意末尾没有空格,在此提供两种方法:
(1)(适用于知道一共有多少个输出的情况) 记录输出次数,最后一次输出时不输出空格(本例中使用的方法)
(2)(不知道输出总数的情况同样适用)设置一个vector,每次要输出时先将要输出的内容push进入vector,最后再统一控制输出。

int preOrder[50], inOrder[50],n;
struct tNode
{
int data;
tNode* left;
tNode* right;
};

//begin1,end1子树先序遍历序列的起点终点,begin2,end2为子树中序遍历的起点终点
tNode* Create(int begin1, int end1, int begin2, int end2)
{
tNode* root = new tNode;
//子树的根为先序遍历序列的起点
root->data = preOrder[begin1];
int index;
for (int i = begin2; i <= end2; i++)
if (inOrder[i] == preOrder[begin1])
index = i;
int leftNum = index - begin2;
int rightNum = end2 - index;
if (leftNum == 0)
root->left = NULL;
else
root->left = Create(begin1 + 1, begin1 + leftNum, begin2, index - 1);
if (rightNum == 0)
root->right = NULL;
else
root->right = Create(begin1 + leftNum + 1, end1, index + 1, end2);
return root;
}

int rec = 0;
//后续遍历
void postOrder(tNode* root)
{
if (root->left != NULL)
postOrder(root->left);
if (root->right != NULL)
postOrder(root->right);
printf("%d",root->data);
rec++;
if (rec < n)
printf(" ");
}

int main()
{
int count1=0, count2=0;
string in;
stack<int> s;
scanf("%d\n", &n);
for (int i = 0; i < 2 * n; i++)
{
cin >> in;
if (in=="Push")
{
int num;
scanf("%d", &num);
s.push(num);
preOrder[count1++] = num;
}
else
{
int num = s.top();
s.pop();
inOrder[count2++] = num;
}
}
tNode* root = Create(0, n - 1, 0, n - 1);
postOrder(root);

}

1102 Invert a Binary Tree (25分)

由于题目中给出的是结点左右孩子的编号,所以可以用二叉树的静态实现。
需要注意的是,交换左右结点的方法中,参数应该是结点的引用

int n; //共有多少个节点
struct tNode
{
int data;
int left;
int right;
}tnodes[20];

//其实相当于一个后续遍历,只不过此时对根节点的操作是交换其左右节点
void Exchange(tNode &t)
{
if (t.left != -1)
Exchange(tnodes[t.left]);
if (t.right != -1)
Exchange(tnodes[t.right]);
int temp=t.left;
t.left = t.right;
t.right = temp;
}
int rec= 0;
void inOrder(tNode t)
{
if (t.left != -1)
inOrder(tnodes[t.left]);
//控制最后不多空格
rec++;
if(rec==n)
printf("%d", tnodes[t.data]);
else
printf("%d ", tnodes[t.data]);
if (t.right != -1)
inOrder(tnodes[t.right]);
}
int flag = 0;
void Level(tNode t)
{
queue<tNode> q;
q.push(t);
while (!q.empty())
{
tNode tt = q.front();
if (flag == 0)
{
printf("%d", tt.data);
flag = 1;
}
else
printf(" %d", tt.data);
q.pop();
if (tt.left != -1)
q.push(tnodes[tt.left]);
if (tt.right != -1)
q.push(tnodes[tt.right]);
}
}

int main()
{

scanf("%d", &n);
char left, right;
bool hasParent[20] = { false };
for (int i = 0; i < n; i++) {
cin>>left>>right;
tnodes[i].data = i;
if (left == '-')
tnodes[i].left = -1;
else {
tnodes[i].left = left - '0';
hasParent[tnodes[i].left] = true;
}
if (right == '-')
tnodes[i].right = -1;
else {
tnodes[i].right = right - '0';
hasParent[tnodes[i].right] = true;
}
}
//找根节点
int root;
for (int i = 0; i < n; i++)
if (hasParent[i] == false)
root = i;
Exchange(tnodes[root]);
Level(tnodes[root]);
printf("\n");

inOrder(tnodes[root]);
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
xiaoyue_666 发布了9 篇原创文章 · 获赞 1 · 访问量 199 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: