PTA L2-011 玩转二叉树 (25 分) 超容易理解做法

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]);
     }
}

有疑惑欢迎留言,一起交流

你可能感兴趣的:(PTA-天梯赛)