L2-011 玩转二叉树

1.题目

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

2.分析

        由于本题的N的范围在30以内,因此我们利用静态的二叉树也可以完成(无指针),题目中说要把二叉树做个镜面反转。

        我会给出静态和动态的两种解法。(其实二者大体思路差不多)

        二叉树进行(左子树,根节点,右子树)地递归就是其前序遍历

        二叉树进行(右子树,根节点,左子树)地递归就是其镜像的前序遍历

题目给出二叉树的中序和前序遍历。

        先给出还原二叉树的代码:

void addTree(int a,int b,int uns){
    if(a>b) return;
    t[uns].w=front[n++];
    t[uns].l=uns*2;                 //定义其左子树的下标为2*uns
    t[uns].r=uns*2+1;               //定义其右子树的下标为2*uns+1
    int i;
    for( i=a;i<=b;i++){
        if(t[uns].w==center[i])
            break;
    }                               //因为是前序遍历,先左后右
    addTree(a,i-1,2*uns);           //递归左子树
    addTree(i+1,b,2*uns+1);         //递归右子树
}

        但这样只能构建出二叉树,并没有对其进行镜像反转(非叶结点的左右孩子对换);

因此我们可以在递归时改变其左右子树

addTree(a,i-1,2*uns+1);
addTree(i+1,b,2*uns);

        经过对比,我们相当于变相交换了 非叶结点的左右孩子。

        

        动态也一样

root->l = addtree(a,i-1);
root->r = addtlree(i+1,b);

        变成

root->r = addtree(a,i-1);
root->l = addtree(i+1,b);

这样就好办了,我们只需要利用队列对其进行层序遍历就行了。

3.代码

静态.........................

#include<iostream>
#include<queue>
using namespace std;
const int MAX=10010;

//树的结构体
struct tree{
    int l,r,w;
}t[MAX];
int N,front[MAX],center[MAX],n=1;      //n用于记录前序下标
void addTree(int a,int b,int uns){
    if(a>b) return;
    t[uns].w=front[n++];               
    t[uns].l=uns*2;                    //左子树
    t[uns].r=uns*2+1;                  //右子树
    int i;
    for( i=a;i<=b;i++){
        if(t[uns].w==center[i])        
            break;
    }
    addTree(a,i-1,2*uns+1);
    addTree(i+1,b,2*uns);
}

//层序遍历
void bfs(){
    queue<int> q;
    q.push(1);
    int f=0;
    while(!q.empty()){
        int x=q.front();
        if(t[x].w){
            if(f) cout<<" "<<t[x].w;
            else f=1,cout<<t[x].w;
        }
        q.pop();
        if(t[x].l) q.push(t[x].l);
        if(t[x].r) q.push(t[x].r);
    }
}
int main(){
    cin>>N;
    for(int i=1;i<=N;i++){cin>>center[i];}
    for(int i=1;i<=N;i++){cin>>front[i];}
    addTree(1,N,1);
    bfs();
    return 0;
}

        动态............................

#include<iostream>
#include<queue>
using namespace std;

//二叉树的结构体
struct Tree{
	int value;
	Tree* l, * r;
};
int N,center[40],front[40],n=1;  //n用来记录前序下标

//建树函数
Tree* addtree(int a,int b){
	if (a > b) return NULL;
	Tree* root = new Tree;
	root->value = front[n++];
	root->l = NULL;
	root->r = NULL;
	int i;
	for (i = a; i <= b; i++) {
		if (root->value == center[i]) break;
	}
	root->r = addtree(a,i-1);           //变相交换左右子树
	root->l = addtree(i+1,b);
	return root;
}

//层序遍历
void bfs(Tree* root) {
	if (root == nullptr) {return;}
	queue<Tree*> q;
	q.push(root);
	int f = 0;
	while (!q.empty()) {
		Tree* t = q.front();
		q.pop();
		if (f) cout << " " << t->value;
		else f = 1, cout << t->value;
		if (t->l) {q.push(t->l);}
		if (t->r) {q.push(t->r);}
	}
}
int main()
{
	cin >> N ;
	for (int i = 1; i <= N; i++) { cin >> center[i]; }
	for (int i = 1; i <= N; i++) { cin >> front[i]; }
	Tree* r = addtree(1,N);
	bfs(r);
	return 0;
}

 

 

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值