树-根据前序、中序遍历求后续遍历

xiaoxiao2021-02-28  40

题目要求 03-树3 Tree Traversals Again (25分)分析 我刚开始的想法是直接根据给出的操作构建相应的树,然后后序遍历即可。我的方法一代码(java版) import java.util.*; class Tree{ public int left = -1; //-1 means null public int right = -1; } public class Tree3 { public static Tree[] tree = new Tree[31]; public static boolean flag = false; //后序遍历 public static void postorderTraversal(int t){ if(t == -1) return; if(tree[t].left != -1){ postorderTraversal(tree[t].left); } if(tree[t].right != -1){ postorderTraversal(tree[t].right); } if(!flag){ System.out.print(t); flag = true; }else { System.out.print(" "+t); } } public static void main(String[] args) { Stack<Integer> stack = new Stack<Integer>(); for(int i=0; i<31; i++){ tree[i] = new Tree(); } Scanner in = new Scanner(System.in); int N = in.nextInt(); String line = null; int nowNode = -1, root = -1; boolean getRoot = false; in.nextLine();//注意这儿需要多加一个nextLine()来跳过第一行 for(int i=1; i<=2*N; i++){ line = in.nextLine(); if(line.startsWith("Push")){ if(!getRoot){//没有根的话,肯定先是构造根结点 nowNode = Integer.parseInt(line.split(" ")[1]); root = nowNode; getRoot = true; }else {//有根的话,push进来的必然是某个结点的子树 int tmp = Integer.parseInt(line.split(" ")[1]); if(tree[nowNode].left == -1){ tree[nowNode].left = tmp; }else { tree[nowNode].right = tmp; } nowNode = tmp; } stack.push(nowNode); }else { nowNode = stack.pop(); } } //后序遍历 postorderTraversal(root); System.out.println(); } }

这样的代码是正确的,但是需要操作比较小心,而且这是凭自己的感觉来做的,我不太能解释清楚这样为什么是对的,虽然最后也通过了,但我感觉这不是一个完美的方法。所以我就百度了一下,发现更好的方法是这样: 其实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; }
转载请注明原文地址: https://www.6miu.com/read-76405.html

最新回复(0)