这样的代码是正确的,但是需要操作比较小心,而且这是凭自己的感觉来做的,我不太能解释清楚这样为什么是对的,虽然最后也通过了,但我感觉这不是一个完美的方法。所以我就百度了一下,发现更好的方法是这样: 其实push的顺序就是这棵树的前序遍历的顺序,pop的顺序就是中序遍历的顺序。那么这道题便转化为了已知前序、中序遍历,求后序遍历。这个函数只需要递归求解就可以了。 - 我的方法二代码 (C++版)
#include <iostream> #include <stack> using namespace std; const int maxn = 31; stack<int> s; //保存前序、中序、后序遍历的顺序的数组 int preOrder[maxn],inOrder[maxn],postOrder[maxn]; void getPostOrder(int i,int j,int k,int n){ if(n == 0) return; //在前序遍历数组上找到根结点root int root = preOrder[i]; postOrder[k+n-1] = root;//把root放在后序遍历数组上相应的位置 //在中序遍历数组上找到根结点的位置 int index; for(index=j; index<j+n; index++){ if(inOrder[index] == root){ break; } } //求左右子树的长度 int L = index-j,R = j+n-index-1; //递归求解 getPostOrder(i+1, j, k, L);//处理左子树 getPostOrder(i+L+1, j+L+1, k+L, R);//处理右子树 } int main(int argc, const char * argv[]) { int N,x; int index1 = 1, index2 = 1; //preOrder[],inOrder[]的下标,从1开始 string op; cin>>N; //根据输入得到前序、中序遍历的顺序 for(int i=1; i<=2*N; i++){ cin>>op; if(op.compare("Push") == 0){ cin>>x; s.push(x); preOrder[index1++] = x; }else{ inOrder[index2++] = s.top(); s.pop(); } } //求后序遍历 getPostOrder(1, 1, 1, N); //输出 cout<<postOrder[1]; for(int i=2; i<=N; i++){ cout<<" "<<postOrder[i]; } cout<<endl; return 0; }