PAT 1020
利用后序遍历和中序遍历建树并用层序遍历输出这棵树
原题翻译后为:
详细代码和注释:
/**
* 题目就是给出树的后续和中序遍历
* 求出这颗树,并用层序遍历输出结果
*/
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int maxn=50;
//创建节点对象
struct node{
int data; //数据域
node *lchild;
node *rchild;
};
int pre[maxn],in[maxn],post[maxn]; //在程序的外部把先序、中序、后序的数组给定义好
int n; //节点个数
//当前二叉树的后续遍历区间为[postL,postR],中序遍历的序列为[inL,inR]
//create函数返回构建出的二叉树的根结点的地址
//参数我只要序列的左右数据即可,不需要有节点的地址等信息
node* create(int postL,int postR,int inL,int inR){
//递归边界
if (postL>postR)
{
return NULL; //后序序列长度小于0时,直接返回为NULL
}
//新建一个新的节点,用来存放当前二叉树的根节点
node* root = new node;
//完善结构体的信息
root->data=post[postR];
root->lchild=NULL;
root->rchild=NULL;
接下来是查找中序遍历中的位置在哪里,以确定左子树和右子树
int k,numLeft;
for ( k=inL ; k<=inR; k++)
{
if (post[postR]==in[k])
{
numLeft=k-inL;
break;
}
}
root->lchild=create(postL,postL+numLeft-1,inL,inL+numLeft-1);
root->rchild=create(postL+numLeft,postR-1,inL+numLeft+1,inR);
return root;
}
//层序遍历访问刚刚建好的树结构
int num=0; //定义一个变量目的是表示已经输出的结点的个数以便最后一个节点后不输出空格
//层序遍历输出结果
void BFS(node *root){
//建立一个队列
queue<node*> q;
//队列的最常见用法是干什么的?
//将根节点加入到队列中,然后从中取出去,将它的子孙节点再放入队列中
q.push(root);
node *tmp_node=NULL;
//栈、队列使用前都需要验证是否为空
while (!q.empty())
{
tmp_node = q.front();
//弹出队首元素
q.pop();
printf("%d",tmp_node->data);
//已经输出的节点个数
num++;
if (num<n) printf(" ");
//放入子孙节点
if ( tmp_node->lchild!=NULL) q.push(tmp_node->lchild); //左子树非空放入左子树
if ( tmp_node->rchild!=NULL) q.push(tmp_node->rchild); //右子树非空放入右子树
}
}
int main(){
scanf("%d",&n);
int tmp;
for (int i = 0; i < n; i++)
{
scanf("%d",&tmp);
post[i]=tmp;
}
for (int i = 0; i < n; i++)
{
scanf("%d",&tmp);
in[i]=tmp;
}
node *tree=create(0,n-1,0,n-1);
BFS(tree);
return 0;
}