L2-011 玩转二叉树 (25分)
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
输出样例:
4 6 1 7 5 3 2
1.首先,先序,中序建树。用一个数组储存树,先输入根节点,再输入左子树,在输入右子树。
传入先序,中序,数组开始到结束的长度,要赋值的坐标
void creatT(int *xian,int *zhong,int n,int index){
if(n==0) return ;//递归出口
int k=0;
while(xian[0]!=zhong[k]) k++;
tree[index]=xian[0];//找到根节点在中序的位置
creatT(xian+1,zhong,k,index*2);//建树左子树
creatT(xian+k+1,zhong+k+1,n-k-1,index*2+1);//建树右子树
}
因为先序第一个节点为根节点,建左子树时数组地址+1,长度为k
建右子树,数组地址+k+1,长度n-k-1,因为要除去根节点
2.把tree[]数组顺序输出就是层序遍历,但需要翻转,所以用队列层次遍历,入队时先考虑右子树,在考虑左子树即可;
代码
#include
using namespace std;
int n,t=0;
int xian[100],zhong[100];
int tree[10000],tree1[10000];
void creatT(int *xian,int *zhong,int n,int index){
if(n==0) return ;
int k=0;
while(xian[0]!=zhong[k]) k++;
tree[index]=xian[0];
creatT(xian+1,zhong,k,index*2);//左
creatT(xian+k+1,zhong+k+1,n-k-1,index*2+1);//右
}
void level(){
queue<int> q;
q.push(1);//初始化队列
while(!q.empty()){
int p=q.front();
q.pop();
tree1[t++]=tree[p];//因为输出规则限制
//需要把反过来的重新存起来,按规则输出
if(tree[p*2+1]!=0) q.push(p*2+1);//进队右子树下标
if(tree[p*2]!=0) q.push(p*2);//进队左子树下标
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&zhong[i]);
for(int i=0;i<n;i++) scanf("%d",&xian[i]);
creatT(xian,zhong,n,1);
level();
for(int i=0;;i++){
if(tree1[i]==0) break;
if(i==0) printf("%d",tree1[i]);
else if(i!=0) printf(" %d",tree1[i]);
}
}
有疑惑欢迎留言,一起交流