题意:根据进栈和出栈的操作可以得到一个二叉树的中序遍历,然后输出后序遍历
思路:可以看出每个进栈的顺序就是先序遍历的顺序,而出栈的顺序就是一个中序遍历的结果,故此题就是根根据先序和中序找后序的过程。此题我参考了柳神的代码用pre和in保存值得索引,而我自己做的是直接保存的值,两种方法都能AC
自己的代码:
#include<iostream>
#include<vector>
#include<stack>
#include<string>
using namespace std;
vector<int> pre, in,post;
stack<int> s;
int n = 0, num = 0, tem = 0,key = 0;
void postTravel(int inL,int inR,int preRoot) {//后序遍历
if (inL > inR)return;
int i = inL;
while (i < n&&in[i] != pre[preRoot]) i++;
postTravel(inL, i - 1, preRoot + 1);
postTravel(i+1, inR, preRoot+(i-inL)+1);
post.push_back(in[i]);
}
int main() {
string str;
cin >> n;
for (int i = 0; i < 2 * n; i++) {
cin >> str;
if (str[1] == 'u') {//push进栈的顺序即为先序遍历
cin >> num;
pre.push_back(num);
s.push(num);
}
else {//出栈的顺序即为中序遍历
tem = s.top();
in.push_back(tem);
s.pop();
}
}
postTravel(0,n-1,0);
for (int i = 0; i < post.size();i++) {
printf("%d%s", post[i], i == post.size() - 1 ? "\n" : " ");
}
system("pause");
return 0;
}
柳神的代码:
#include <cstdio>
#include <vector>
#include <stack>
#include <cstring>
using namespace std;
vector<int> pre, in, post,value;
void postorder(int root, int start, int end) {
if (start > end) return;
int i = start;
while (i < end && in[i] != pre[root]) i++;
postorder(root + 1, start, i - 1);
postorder(root + 1 + i - start, i + 1, end);
post.push_back(pre[root]);
}
int main() {
int n;
scanf("%d", &n);
char str[5];
stack<int> s;
int key=0;
while (~scanf("%s", str)) {
if (strlen(str) == 4) {
int num;
scanf("%d", &num);
value.push_back(num);
pre.push_back(key);
s.push(key++);
} else {
in.push_back(s.top());
s.pop();
}
}
postorder(0, 0, n - 1);
printf("%d", value[post[0]]);
for (int i = 1; i < n; i++)
printf(" %d",value[post[i]]);
return 0;
}
核心思想都差不多,就是用pre和in保存值和索引的问题,其余小的细节可以比较