题目大意:
用栈来模拟一颗二叉树的先序和中序遍历过程,求这课树的后序遍历序列。
算法思路:
首先得说一个结论,就是栈的入栈序列就是一颗二叉树的先序遍历,出栈序列就是一颗二叉树的中序遍历序列,那么这个题目就转化为根据先序和中序求后序遍历序列。那么首先就是根据先序和中序建立二叉树,然后根据这个二叉树进行后序遍历获得后序遍历序列。
递归建立二叉树
假设递归过程中某步的前序区间是$[beginPre,lastPre]$,中序区间是$[beginIn,lastIn]$,那么根节点为$pre[beginPre]$,首先初始化根节点$root$,接着需要在中序遍历中找到根节点的位置$index_root$,然后计算左子树的个数leftTreeLen = index_root-beginIn;
这样左子树和右子树在后序和中序遍历中就分开了,紧接着就是左子树递归:
root->left =createTree(beginPre+1,beginPre+leftTreeLen,beginIn,index_root-1);
右子树递归:
root->right = createTree(beginPre+leftTreeLen+1,lastPre,index_root+1,lastIn);
递归的边界就是在区间长度小于0的时候直接返回空即可。
注意点:
- 1、输入的行数为N的2倍。
提交结果:
AC代码:
#include <stack>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
struct Node{
int data;
Node* left;
Node* right;
};
int N;// 节点个数
vector<int> pre,In;
Node* createTree(int beginPre,int lastPre,int beginIn,int lastIn){
if(beginPre>lastPre) return nullptr;
// 初始化根节点
Node* root = new Node;
root->data = pre[beginPre];
// 在中序序列
int index_root;
for(index_root=beginIn;index_root<=lastIn;++index_root){
if(In[index_root]==root->data) break;
}
int leftTreeLen = index_root-beginIn;
root->left = createTree(beginPre+1,beginPre+leftTreeLen,beginIn,index_root-1);
root->right = createTree(beginPre+leftTreeLen+1,lastPre,index_root+1,lastIn);
return root;
}
int num = 0;// 输出节点的个数,用来控制输出
void postTraverse(Node* root){
if(root== nullptr) return;
postTraverse(root->left);
postTraverse(root->right);
printf("%d",root->data);
if(num<N-1) printf(" ");
++num;
}
int main()
{
scanf("%d",&N);
string s;
int num;
stack<int> st;
// 输入的数据有2*N行
for (int i = 0; i < 2*N; ++i) {
cin>>s;
if(s=="Push"){
scanf(" %d",&num);
st.push(num);
pre.push_back(num);
} else {
num = st.top();
st.pop();
In.push_back(num);
}
}
Node* root = createTree(0,N-1,0,N-1);
postTraverse(root);
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。