`//用栈来模拟一棵二叉树的先序和中序遍历过程,求这棵二叉树的后序遍历序列
// 6
// Push 1
// Push 2
// Push 3
// Pop
// Pop
// Push 4
// Pop
// Pop
// Push 5
// Push 6
// Pop
// Pop
//push的次序为1、2、3、4、5、6
//因此先序遍历的序列为123456
//pop的次序为3、2、4、1、6、5
//因此中序遍历的序列是342651
//任何2个序列组合,都一定要有中序
//每次访问一个新节点时就把它入栈,这个过程和先序序列总是先访问根节点的性质是相同的
//入栈顺序(push)就是先序遍历序列中元素的顺序
//pop则总是按照做左 根 右的顺序进行的
//直到找不到某个节点(最下面的那个的)左孩子了,就去找的右孩子,但在这之前,要把左孩子去掉,根节点去掉
//再去压入右孩子压入,重复上述步骤
//于是,问题就转换为了:给出一棵二叉树的先序遍历序列和中序遍历序列,重构出该二叉树,
//并输出其后续序列,写法非常固定
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
struct node{
int data;
node* lchild;
node* rchild;
};
int n,pre[110],post[110],in[110];
node* createTree(int preL,int preR,int inL,int inR){
if(preL>preR)return NULL;
node* root=new node;
root->data=pre[preL];
int k;
for(k=inL;k<inR;k++){
if(pre[preL]==in[k]){
//k=3
break;
}
}
int leftNum=k-inL;//leftNum=3
//1 2 3 4 5 6
//3 2 4 1 6 5
//1---2 3 4 5 6
//3 2 4----1----6 5
//1 ----2 3 4---- 5 6
root->lchild=createTree(preL+1,preL+leftNum,inL,k-1);//1,3
root->rchild=createTree(preL+leftNum+1,preR,k+1,inR);//4,5
return root;
}
int num=0;//已经输出的节点个数
void postorder(node* root){
//后序遍历
if(root == NULL){
return;
}
postorder(root->lchild);
postorder(root->rchild);
printf("%d",root->data);
num++;
if(num<n)printf(" ");
}
int main()
{
scanf("%d",&n);
char str[5];
stack<int>st;
int x,preIndex=0,inIndex=0;//入栈元素、先序序列位置及中序序列位置
for(int i=0;i<2*n;i++){
//一共入栈2n次//Push 1
scanf("%s",str);//Push
if(strcmp(str,"Push")==0){
//入栈----==0相同
scanf("%d",&x);//1
pre[preIndex++]=x;//令pre[preIndex]=x
st.push(x);//用栈的入栈和出栈来模拟树的遍历
}else{
// Pop
in[inIndex++]=st.top();//令in[inIndex]=st.top()
st.pop();//用栈的入栈和出栈来模拟树的遍历
}
}
node* root=createTree(0,n-1,0,n-1);
postorder(root);
return 0;
}`
|栈模拟pre、in,求post|1086 Tree Traversals Again (25分)
猜你喜欢
转载自blog.csdn.net/weixin_44769957/article/details/109035614
今日推荐
周排行