原题链接
解题思路
常规的遍历树题,主要是如何反转二叉树?只要在后序遍历访问根结点时,交换左右子树即可,从最底层开始交换左右子树。
反转之后进行层序遍历和中序遍历即可。
发现不反转也可以进行符合要求的层序遍历,只要每次先让队列首的右结点入队,再让左结点入队就可以了,但是如何不反转树得到符合要求的中序遍历还没有想到可行方便的办法。
源代码
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 15;
int n;
bool ischild[maxn] = {false};
struct node{
int left;
int right;
}tree[maxn];
void postInvert(int root){
if(root == -1) return ;
postInvert(tree[root].left);
postInvert(tree[root].right);
swap(tree[root].left, tree[root].right);
}
int idx = 0;//控制行末不多出空格
void levelOrderTraversal(int root){
//层序遍历这里只要先让右子树入队,再让左子树入队就可以实现反转
queue<int> q;
q.push(root);
while(!q.empty()){
int top = q.front();
printf("%d", top);
if(idx != n-1)
printf(" ");
else
printf("\n");
idx ++;
q.pop();
if(tree[top].right != -1) q.push(tree[top].right);
if(tree[top].left != -1) q.push(tree[top].left);
}
}
int idx1 = 0;
void inOrderTraversal(int root){
if(root != -1){
inOrderTraversal(tree[root].left);
printf("%d", root);
if(idx1 != n-1)
printf(" ");
idx1++;
inOrderTraversal(tree[root].right);
}
}
int main(){
scanf("%d", &n);
getchar();
char a, b;
for(int i=0; i<n; i++){
scanf("%c %c", &a, &b);
getchar();
if(a == '-')
tree[i].left = -1;
else{
tree[i].left = a-'0';
ischild[a-'0'] = true;
}
if(b == '-')
tree[i].right = -1;
else{
tree[i].right = b-'0';
ischild[b-'0'] = true;
}
}
//找根结点
int root = -1;
for(int i=0; i<n; i++){
if(ischild[i] == false){
root = i;
break;
}
}
//层序遍历
levelOrderTraversal(root);
//后序遍历翻转二叉树
postInvert(root);
//中序遍历
inOrderTraversal(root);
return 0;
}