#include <cstdio> //调用标准C语言库
#include <cstring> //调用字符串标准库
#include <queue> //调用队列标准库
#include <algorithm> //调用算法标准库
using namespace std; //使用命名空间
const int maxn = 50; //提前定义整数maxn
//定义结点node结构体,结构体里包括数据,左子树指针,右子树指针
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时,直接返回
}
node* root = new node; //新建一个node类型的结点,用来存放当前二叉树的根节点
root->data = post[postR]; //新建的根节点即为后序序列的最后一个元素,将其赋值给当前根节点
int k;
for(k = inL; k <= inR; k++) //遍历中序序列,找到节点值为当前根节点值的元素
{
if(in[k] == post[postR])
break;
}
int numleft = k - inL; //找到中序序列对应根节点后,左子树的节点个数
//返回左子树的根节点地址,赋值给root的左指针
root -> lchild = create(postL, postL + numleft - 1, inL, k - 1);
//返回右子树的根节点地址,赋值给root的右指针
root -> rchild = create(postL + numleft, postR - 1, k + 1, inR);
return root; //返回根节点地址
}
int num = 0; //已输出的结点个数
void BFS(node* root){
queue<node*> q; //定义输出队列,队列里存放的是地址
q.push(root); //将 根节点地址 入队
while(!q.empty()) //当队列非空时
{
node* now = q.front(); //取出队首元素,q.front()目前是一个地址(node* 类型),将其赋值给now
q.pop(); //赋值后,删除队首元素
printf("%d", now -> data); //访问队首元素
num++;
if(num < n)
printf(" "); //元素之间加空格
if(now -> lchild != NULL) //当now所指左子树非空时
q.push(now -> lchild); //将其所指左子树加入队列
if(now -> rchild != NULL) //当now所指右子树非空时
q.push(now -> rchild); //将其所指右子树加入队列
}
}
int main()
{
scanf("%d", &n); //输入结点个数
for(int i = 0; i < n; i++)
{
scanf("%d", &post[i]); //输入后序序列
}
for(int i = 0; i < n; i++)
{
scanf("%d", &in[i]); //输入中序序列
}
node* root = create(0, n - 1, 0, n - 1); //创建根结点为root的二叉树
BFS(root); //层序访问根结点所指向的二叉树
return 0;
}
【PAT A1020】 Tree Traversals(树的遍历)
于 2023-04-14 16:43:07 首次发布