题目
给出中序和前序遍历,求后序遍历,只不过是间接的给出了遍历序列
Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
Sample Output:
4 2 6 5 1
代码和思路
- 先是对输入的处理,可以直接用string,然后判断第二个字符是什么来判断是输入还是输出,栈的话不需要手写栈,直接用STL就行
- push的顺序就是他的前序遍历,pop出的序列是中序遍历
- 在处理完输入后就会得到两个序列了
- 这次使用重构整棵树的方法来进行遍历,下标变换的话太绕了
- 对于每个序列,前序遍历的第一个一定是这串序列的根节点,然后去中序遍历中找到这个节点的位置,则这个节点的左边是他的左子树,右边是右子树,然后递归进行构树,具体的递归细节和递归出口在下面的代码中进行解释
#include<cstdio>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
struct node {
int data;
node* lchild;
node* rchild;
};
stack<int> s;
int Inorder[31];
int Preorder[31];
int Postorder[31];
int n;
node* creat(int preL, int preR, int inL, int inR) {
//证明整个Pre序列都已经被构建了
if (preL > preR) return NULL;
node* root = new node;
root->data = Preorder[preL];
int k;
for (k = inL; k <= inR; k++) {
if (Inorder[k] == Preorder[preL]) {
break;
}
}
int numleft = k - inL;
root->lchild = creat(preL + 1, preL + numleft, inL, k - 1);
root->rchild = creat(preL + numleft + 1, preR, k + 1, inR);
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() {
string str;
scanf_s("%d", &n);
getchar();
getline(cin, str);
int indexp = 0;
int indexpt = 0;
int size = 1;
s.push(str[str.length() - 1] - '0');
Preorder[indexp++] = str[str.length() - 1] - '0';
int indexi = 0;
while (size < n || !s.empty()) {
getline(cin, str);
if (str[1] == 'u') {
s.push(str[str.length() - 1] - '0');
Preorder[indexp++] = str[str.length() - 1] - '0';
size++;
}
else {
Inorder[indexi++] = s.top();
s.pop();
}
}
node* root = creat(0, n - 1, 0, n - 1);
postorder(root);
return 0;
}