团体天梯练习 L2-035 完全二叉树的层序遍历

发布时间 2023-04-20 00:18:12作者: Amαdeus

L2-035 完全二叉树的层序遍历

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 \(D\) 的,有 \(N\) 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 \(N\) 个结点,这样的树就是完全二叉树。

给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果。

输入格式:

输入在第一行中给出正整数 \(N\)\(≤30\) ),即树中结点个数。第二行给出后序遍历序列,为 \(N\) 个不超过 \(100\) 的正整数。同一行中所有数字都以空格分隔。

输出格式:

在一行中输出该树的层序遍历序列。所有数字都以 \(1\) 个空格分隔,行首尾不得有多余空格。

输入样例:

8
91 71 2 34 10 15 55 18

输出样例:

18 34 55 71 2 10 15 91


解题思路

题目中给出的是二叉树的后序遍历序列,而要求得完全二叉树的层序遍历序列。将完全二叉树以数组形式存储,某个节点的下标为 \(i\) (下标从1开始),那么其左右孩子的下标分别为 \(2 * i\)\(2 * i + 1\),可以看出数组形式存储的完全二叉树的顺序遍历序列其实就正好是其层序遍历序列。

对于建立二叉树,用一个递归函数实现即可。由于给出的是后序遍历序列,我们需要先深度优先建立左子树,再深度优先建立右子树,最后给根节点赋值,其实和二叉树的后序遍历是完全类似的操作。

\([[leftPostOrder],[rightPostOrder],root]\)

/*   一切都是命运石之门的选择  El Psy Kongroo  */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, int> psi;
//typedef __int128 int128;
#define PI acos(-1.0)
#define x first
#define y second
//int dx[4] = {1, -1, 0, 0};
//int dy[4] = {0, 0, 1, -1};
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;


const int N = 35;
int post[N], res[N], cnt, n;

void dfs(int idx){
    if(idx > n) return;
    dfs(idx << 1);       //深度优先建立左子树
    dfs(idx << 1 | 1);   //深度优先建立右子树
    res[idx] = post[ ++ cnt];
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n;
    for(int i = 1; i <= n; i ++ ) cin >> post[i];

    dfs(1);

    for(int i = 1; i < n; i ++ ) cout << res[i] << ' ';
    cout << res[n] << endl;

    return 0;
}