注意:
中序序列可以与任意一个序列(先序、后序、蹭序)构建唯一的二叉树,但后三者无论两个还是三个一起搭配都无法构建唯一的二叉树:因为先序、后序、层序均是提供根节点,作用相同,必须有中序序列来区分左右子树。
先序中序——>后序
题目描述
现有一棵n个结点的二叉树(结点编号为从0
到n-1
),已知其先序序列和中序序列,求后序序列。
输入描述
第一行一个整数n(1≤n≤50),表示二叉树的结点个数;
第二行为n个整数,表示二叉树的先序序列;
第三行为n个整数,表示二叉树的中序序列。
输出描述
输出n个整数,表示二叉树的后序序列,中间用空格隔开,行末不允许有多余的空格。
样例1
输入
6 0 2 1 4 5 3 1 2 4 0 5 3
输出
1 4 2 3 5 0
(这个书上的思路图我觉得非常清楚了!!!超赞)
#include<bits/stdc++.h>
using namespace std;
vector<int> pre,in,post; //vector容器方便处理最后一个满足条件的数据后不输出额外的空格。
struct node{
int data;
node* lchild; //二叉链表定义
node* rchild;
};
int n; //节点数目
node* create(int preL,int preR,int inL,int inR)
{
if(preL>preR) //先序序列长度<=0,直接返回
return NULL;
node* root=new node; //新结点存放当前二叉树的根节点
root->data=pre[preL]; //新结点的数值为根节点的值
int numLeft; //左子树结点个数
int k;
for(k=inL;k<=inR;k++)
{
if(in[k]==pre[preL]) //在中序序列中找根节点的位置
{
break;
}
}
numLeft=k-inL;
root->lchild=create(preL+1,preL+numLeft,inL,k-1);
root->rchild=create(preL+numLeft+1,preR,k+1,inR);
return root;
}
void postorder(node* root)
{
if(!root) return;
postorder(root->lchild); //后序遍历
postorder(root->rchild);
post.push_back(root->data); //将数值保存至vector容器中
}
int main()
{
int x;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
pre.push_back(x);
}
for(int i=0;i<n;i++)
{
scanf("%d",&x);
in.push_back(x);
}
node* root=create(0,n-1,0,n-1); //注意这一步写啥(int-输入的是下标)
postorder(root);
for(int i=0;i<(int)post.size();i++)
{
printf("%d",post[i]);
if(i<(int)post.size()-1)
printf(" ");
}
return 0;
}
后序中序——>先序
pta线上作业(8-10周)——>4-15 根据后序和中序遍历输出先序遍历(15分)
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder:
以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
Preorder: 4 1 3 2 6 5 7
思路图:(基本同上,要注意左右子树的头尾下标问题)
#include<bits/stdc++.h>
using namespace std;
struct node{
int data;
node *lchild;
node *rchild;
};
vector<int> pre,post,in;
node* create(int postl,int postr,int inl,int inr)
{
//递归终止条件
if(postl>postr)
return NULL;
node *root=new node;
root->data=post[postr];
int k;
for(k=inl;k<=inr;k++)
{
if(in[k]==post[postr])
break;
}
int numleft=k-inl;
root->lchild=create(postl,postl+numleft-1,inl,k-1);
root->rchild=create(postl+numleft,postr-1,k+1,inr);
return root;
}
int num=0;
void preorder(node *root){
if(root==NULL)
return;
pre.push_back(root->data);
preorder(root->lchild);
preorder(root->rchild);
}
int main()
{
int n;
int x;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
post.push_back(x);
}
for(int i=0;i<n;i++)
{
scanf("%d",&x);
in.push_back(x);
}
node* root=create(0,n-1,0,n-1);
printf("Preorder: ");
preorder(root);
for (int i = 0; i < (int)pre.size(); i++) {
printf("%d", pre[i]);
if (i < (int)pre.size() - 1) {
printf(" ");
}
}
return 0;
}
(层序的放在下一篇吧!)