二叉樹的前中後序遍歷,他們的遞歸非遞歸。還有廣度遍歷,參見二叉樹的前中後序遍歷迭代&廣度遍歷和二叉樹的前中後序遍歷簡單的遞歸html
如今記錄已知二叉樹的前序中序後序遍歷的兩個,求另一個。通常,這兩個中必定有中序遍歷。node
一、已知前序和中序,求後序遍歷:函數
前序:ABDECFG 中序:DBEAFCGpost
思路簡單:前序的第一個節點就是根節點,url
中序中找到根節點的位置,根節點以前是其左子樹,以後是右子樹spa
按此順序,依次在左子樹部分遍歷,右子樹部分遍歷code
C++ 代碼:orm
TreeNode *BinaryTreeFormorderings(char *Preorder, char *Inorder, int len) { if(len == 0) return NULL; TreeNode *node=new TreeNode; node->val=*Preorder; int rootIndex=0; while(rootIndex<len) { if(Inorder[rootIndex] == *Preorder) break; ++rootIndex; } node->left = BinaryTreeFormorderings(Preorder+1, Inorder, rootIndex); node->right = BinaryTreeFormorderings(Preorder+rootIndex+1,Inorder+rootIndex+1,len-(rootIndex+1)); cout<<node->val; return node; }
注:上述代碼,實際上是在遍歷的過程當中創建了一個二叉樹並返回,這是最全的。若是隻是要個後續遍歷的序列,能夠在輸出哪裏以一個vector來存放序列就能夠了,不必創建二叉樹的。若是隻是要輸出後續遍歷,則在最後哪裏輸出就能夠了,也不必保存這個vector了。htm
二、已知後和中序,求前序遍歷:相似上述求後序的狀況blog
後序:DEBFGCA 中序:DBEAFCG
思路簡單:後序的最後一個節點就是根節點,
中序中找到根節點的位置,根節點以前是其左子樹,以後是右子樹
按此順序,依次在左子樹部分遍歷,右子樹部分遍歷
C++代碼:
TreeNode *BinaryTreePostorderings(char *Postorder, char *Inorder, int len) { if (len == 0) return NULL; TreeNode *node = new TreeNode; node->val = *(Postorder + len - 1); cout << node->val; int rootIndex = 0; while (rootIndex<len) { if (Inorder[rootIndex] == *(Postorder + len - 1)) break; ++rootIndex; } node->left = BinaryTreePostorderings(Postorder, Inorder, rootIndex); node->right = BinaryTreePostorderings(Postorder + rootIndex, Inorder + rootIndex + 1, len - (rootIndex + 1)); return node; }
注:上述代碼,與前文狀況一致,根據具體狀況須要來完成前序的遍歷。
又寫了一次遍歷方式,用vector存放數據,起點終點,函數參數傳入:
void BinaryTree::PreIn_to_post(std::vector<int> &pre, int first, int end, std::vector<int> &in, int first2, int end2, std::vector<int> &post) { if (pre.size() == 0 || in.size() == 0 || first<0 || end>pre.size()-1 || first2<0 || end2>in.size()-1 ||first>end || first2>end2 || end-first != end2-first2) return; if (first == end) { post.push_back(pre[first]); return; } int index2 = first2; while (index2 <= end2 && in[index2] != pre[first]) ++index2; PreIn_to_post(pre, first + 1, first+index2-first2, in, first2, index2-1, post); PreIn_to_post(pre, first+ 1+index2 -first2, end, in, index2 + 1, end2, post); post.push_back(pre[first]); } void BinaryTree::PostIn_to_pre(std::vector<int> &post, int first, int end, std::vector<int> &in, int first2, int end2, std::vector<int> &pre) { if (post.size() == 0 || in.size() == 0 || first<0 || end>post.size() - 1 || first2<0 || end2>in.size() - 1 || first > end || first2 > end2 || end - first != end2 - first2) return; if (first == end) { pre.push_back(post[end]); return; } int index2 = first2; while (index2 <= end2&&in[index2] != post[end]) ++index2; pre.push_back(post[end]); PostIn_to_pre(post, first, first + (index2 - first2)-1, in, first2, index2 - 1, pre); PostIn_to_pre(post, first + index2 - first2, end - 1, in, index2 + 1, end2,pre); }
三、已知前序後序遍歷,求中序遍歷:
這種狀況並不能徹底的求出全部狀況的二叉樹中序遍歷。由於由前序和後序並不能徹底肯定一顆樹。可是,若是已知是滿二叉樹或者徹底二叉樹的話,我想是能夠的。
前序:中左右 後序:左右中
思路是這樣的:
前序的第一個節點和後序的最後一個節點必定是根節點,
若是前序的第二個節點與後序的倒數第二個節點不相等,那麼前序的第二節點是根的左子樹,後序的倒數第二節點是根的右子樹
(可是 若是前序的第二個節點與後序的倒數第二個節點相等,那就不能肯定究竟是左子樹仍是右子樹了,由於缺省一個子樹中左與左中,中右與右中都會相等。因此這就須要題目有要求該樹的特徵了)
而後再後序中找到左子樹根節點,在後序中從左子樹根節點結合前序左子樹根節點開始遞歸上述獲得根節點左子樹的子樹
一樣在前序中找到右子樹根節點,在前序中從右子樹根節點結合後序右子樹根節點開始遞歸上述獲得根節點右子樹的子樹
改天想寫代碼的時候再來試試貼上吧