PTA 03-树3 Tree Traversals Again

03-树3 Tree Traversals Again

原题链接
An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

在这里插入图片描述
Figure 1

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

Output Specification:
For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
结尾无空行
Sample Output:
3 4 2 6 5 1
结尾无空行

思路

不管PushPop->先序遍历
基于push和pop,进行栈模拟->中序遍历
先序遍历+中序遍历->求后序遍历

核心算法

(根据陈越PTA讲解视频临摹的代码)

//PreL为该伦的先序遍历的开始下标
//inL为该伦的中序遍历的开始下标
//PostL为该伦的后序遍历的开始下标 
//len为该伦递归子串的长度 
void solve(int PreL,int inL,int PostL,int len){
	if(n==0){
		return;//最特殊的情况:末尾时,右子串为空n==0 
	}
	if(n==1){
		post[PostL]=pre[PreL];//只有一个元素的情况下post,int,pre都是相同元素 
	}
	post[PostL+len-1]=pre[PreL];//将先序遍历中的“根节点”存到后序遍历的最后
	int L,R;//左右子串的长度
	for(int i=0;in[i]!=pre[PreL];i++);//寻找该伦根节点的位置
	L=i;//左子串的个数=i
	R=len-i-1;//右子串长度=子串长度- 左子串长度-根节点(1)
	solve(PreL+1,inL,PostL,L); 
	//递归左子串->左子串先序遍历从PreL+1开始,inL,PostL遍历顺序不变 
	solve(PreL+L+1,inL+L+1,PostL+L,R);
	//递归右子串 ->右子串先序遍历从(跳过左子串和根节点长度开始)PreL+L+1
	//中序遍历也是从(跳过左子串和根节点长度开始)inL+L+1
	//后序遍历从(跳过左子串长度开始)PostL+L 
}

//main函数中的调用
solve(0,0,0,len); 

Code

#include<iostream>
#include<stack>
#include<vector>
#define MaxSize 30
using namespace std;
vector<int> postorder;
void postorderPrint(int preorder[],int inorder[],int root,int start,int end){
    if(start>end)
        return;
    int i=start;
    while(i<end&&inorder[i]!=preorder[root]){
        i++;
    }
    postorderPrint(preorder,inorder,root+1,start,i-1);//左子树
    postorderPrint(preorder,inorder,root+(i-start+1),i+1,end);//右子树
    postorder.push_back(preorder[root]);
}
int main(){
    int N,pi=0,ii=0;
    cin>>N;
    stack<int> st;
    int preorder[N],inorder[N];//用来存先序和中序遍历的数组
    int total=2*N;
    //存先序和中序遍历进数组
    while(total--){
        string op;
        cin>>op;
        if(op=="Push"){
            int num;
            cin>>num;
            preorder[pi++]=num;
            st.push(num);
        }else{//POP
            if(!st.empty()){
                inorder[ii++]=st.top();
                st.pop();
            }
        }
    }
    postorderPrint(preorder,inorder,0,0,N-1);
    for(int i=0;i<N;i++){
        if(i!=0){
            printf(" ");
        }
        cout<<postorder[i];
    }
    return 0;
}

先序遍历+中序遍历->后序遍历

参考博客

#include<iostream>
using namespace std;

int pre[]={1, 2, 3, 4, 5, 6};//前序序列
int in[]={3, 2, 4, 1, 6, 5};//中序序列

void post(int root,int start,int ends){//后序打印
  if(start>ends){
    return;
  }
  int i=start;
  while(i<ends&&in[i]!=pre[root]){//找到中序序列中根结点的位置
    i++;
  }
  post(root+1,start,i-1);//遍历左子树
  post(root+(i-start+1),i+1,ends);//遍历右子树
  cout<<pre[root]<<' ';
}

int main(){
  post(0,0,5);
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值