题目链接
题目详情
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 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
解题思路
给出一颗二叉树的结点数N,以及它的后序遍历。要求输出其层序遍历。
首先解释一下两个概念
后序遍历:
对于一颗二叉树而言,后序遍历是指最后遍历根结点(每一颗子树的根结点)即:左 -> 右 -> 根
层序遍历: 一颗二叉树的层序遍历是指,从第一层(根结点)开始,从左往右依次遍历每一层的所有结点。通常,我们用队列来操作。
void levelOrdered(Node* root)
{
queue<Node*> q;
int f = 0;
if (root != NULL)
{
q.push(root);
}
while (!q.empty())
{
if (f == 0) cout << q.front()->data;
else cout <<" "<< q.front()->data;
f++;
if (q.front()->lchild)
{
q.push(q.front()->lchild);
}
if (q.front()->rchild)
{
q.push(q.front()->rchild);
}
q.pop();
}
}
然后,我们要根据题目给出的后序遍历建树。因为我们只能确定后序遍历的最后一个结点为整棵树的根结点。然后创建该结点的右孩子,再创建左孩子(通过递归来实现)。即将后序遍历的过程反过来操作。
Node* create(int id) { //id是该结点的编号
if (id > n)
return NULL;
Node* root = new Node;
root->data = a[k];//最后一个点为根节点
k--;
root->rchild = create(2 * id + 1);//右节点
root->lchild = create(2 * id);//左节点
return root;
}
AC代码
#include<iostream>
#include<queue>
using namespace std;
struct Node
{
int data;
Node* lchild;
Node* rchild;
};
int n, k;
int a[35];
Node* create(int id) {
if (id > n)
return NULL;
Node* root = new Node;
root->data = a[k];//最后一个点为根节点
k--;
root->rchild = create(2 * id + 1);//右节点
root->lchild = create(2 * id);//左节点
return root;
}
void levelOrdered(Node* root)
{
queue<Node*> q;
int f = 0;
if (root != NULL)
{
q.push(root);
}
while (!q.empty())
{
if (f == 0) cout << q.front()->data;
else cout <<" "<< q.front()->data;
f++;
if (q.front()->lchild)
{
q.push(q.front()->lchild);
}
if (q.front()->rchild)
{
q.push(q.front()->rchild);
}
q.pop();
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
k = n - 1;
Node * root = create(1);
levelOrdered(root);
return 0;
}