vlambda博客
学习文章列表

练一练(11)玩转二叉树

给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。

输入格式:

输入第一行给出一个正整数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

/*

* 文件名:玩转二叉树

* 描  述:根据前序、中序序列还原建树,然后镜面反转,就是将

非叶子节点的左右孩子互换,最后层序遍历输出这棵树。

* 作  者:张工

* 时  间:2021-3-4

*/

#include <bits/stdc++.h>

using namespace std;


int n;

int qian[1000], zh[1000];

struct node

{

    int l, r;

} pp[1000];


int build(int la, int ra, int lb, int rb)

{

    if(la > ra)

        return 0;

    int root, p1, p2;

    root = qian[lb];

    p1 = la;

    while(zh[p1] != root)

        p1++;

    p2 = p1 - la;

    pp[root].l = build(la, p1 - 1, lb + 1, lb + p2 - 1);

    pp[root].r = build(p1 + 1, ra, lb + p2 + 1, rb);

    return root;

}

void fan(int root)

{

    if(pp[root].l || pp[root].r)

    {

        int temp = pp[root].l;

        pp[root].l = pp[root].r;

        pp[root].r = temp;

        if(pp[root].l)

            fan(pp[root].l);

        if(pp[root].r)

            fan(pp[root].r);

    }

}

void level()

{

    queue<int>q;

    q.push(qian[0]);

    cout << qian[0];

    while(!q.empty())

    {

        int temp = q.front();

        q.pop();

        if(temp != qian[0])

            cout << ' ' << temp;

        if(pp[temp].l)

            q.push(pp[temp].l);

        if(pp[temp].r)

            q.push(pp[temp].r);

    }

    cout<<endl;

}


int main()

{

scanf("%d",&n);

    for(int i = 0; i < n; i++)

        cin >> zh[i];

    for(int i = 0; i < n; i++)

        cin >> qian[i];

    build(0,n - 1, 0, n - 1);

    fan(qian[0]);

    level();

    

return 0;

}