如何根據二叉樹的前序和中序遍歷得到后序遍歷


  填空題:已知一棵二叉樹前序遍歷和中序遍歷分別為ABDEGCFH和DBGEACHF,則該二叉樹的后序遍歷為_____________。

  答案:DGEBHFCA。

  解題過程:

  一、基本概念掃盲:對一棵二叉樹進行遍歷,我們可以采取3中順序進行遍歷,分別是前序遍歷、中序遍歷和后序遍歷。

  前序遍歷:根節點 -> 左節點 -> 右節點

  中序遍歷:左節點 -> 根節點 -> 右節點

  后序遍歷:左節點 -> 右節點 -> 根節點

  我們可以發現,根節點是帶頭大哥,前序就是大哥打頭陣,中序就是大哥居中指揮,后序就是大哥坐鎮后方。

  二、分析前序和中序的特點:

  1、前序的第一個節點,必然是大哥;

  2、大哥在中序必然居中,自然可以把中序拆分為左右兩顆子樹;

  3、對左右子樹重復上面過程,最終必然能把整顆二叉樹還原出來。

  三、對二叉樹進行后序遍歷。

  四、理論講完了,回歸題目:

  前序遍歷:ABDEGCFH

  中序遍歷:DBGEACHF

  1、從前序找到大哥:A,那么左子樹為:DBGE,右子樹:CHF

      A

     /       \

          DBGE     CHF

 

  2、對左子樹遞歸,從前序找到大哥:B,那么左子樹的左子樹是:D,左子樹的右子樹是:GE

                                                    A

                                                 /      \

                                              B       CHF

                                           /     \

                                        D      GE

 

  3、對左子樹的左子樹沒必要遞歸了,就一個節點D,對左子樹的右子樹遞歸,從前序找到大哥:E,那么左子樹的右子樹的左子樹是:G

                                                                                                   

                                                    A

                                                 /      \

                                              B       CHF

                                           /     \

                                        D        E

                                                 /

                                              G

 

  4、左子樹已經遞歸完,右子樹依葫蘆畫瓢,最終還原出來的二叉樹就是它:

                            

                                                    A

                                                 /      \

                                              B         C

                                           /     \           \

                                        D        E         F

                                                 /              \

                                              G                H

 

  5、對它做后序遍歷:DGEBHFCA

  好了,以上就是解題全過程。作為程序員,應該充分利用手頭的工具來解題——計算機。所以我們需要進一步對該題建模,思考模型的算法。巧了,letCode的第105題就是這個題目,大家可以移步去力扣看題解。這里給出最簡單的遞歸算法實現:

/** * 二叉樹構造,根據前序遍歷、中序遍歷,獲取二叉樹 * @author wulf */ public class BTree { /** * 構造二叉樹 * * @param preOrder 前序遍歷數組 * @param inOrder 中序遍歷數組 * @return */ public TreeNode buildTree(String[] preOrder, String[] inOrder) { return buildTreeByRecursion(preOrder, 0, preOrder.length, inOrder, 0, inOrder.length); } /** * 遞歸構造二叉樹 * * @param preOrder 前序遍歷數組 * @param preOrderStart * @param preOrderEnd * @param inOrder 中序遍歷數組 * @param inOrderStart * @param inOrderEnd */ private TreeNode buildTreeByRecursion(String[] preOrder, int preOrderStart, int preOrderEnd, String[] inOrder, int inOrderStart, int inOrderEnd) { if (preOrderStart == preOrderEnd) { return null; } // 根節點值 String rootValue = preOrder[preOrderStart]; // 構造根節點 TreeNode rootNode = new TreeNode(rootValue); // 在中序遍歷中找到根節點位置 int rootIndex = 0; for (int i = inOrderStart; i < inOrderEnd; i++) { if (inOrder[i].equals(rootValue)) { rootIndex = i; break; } } int leftNum = rootIndex - inOrderStart; // 遞歸的構造左子樹 rootNode.left = buildTreeByRecursion(preOrder, preOrderStart + 1, preOrderStart + leftNum + 1, inOrder, inOrderStart, rootIndex); // 遞歸的構造右子樹 rootNode.right = buildTreeByRecursion(preOrder, preOrderStart + leftNum + 1, preOrderEnd, inOrder, rootIndex + 1, inOrderEnd); return rootNode; } /** * 后續遍歷 * * @param treeNode 二叉樹對象 */ private void postOrder(TreeNode treeNode) { if (treeNode != null) { postOrder(treeNode.left); postOrder(treeNode.right); System.out.print(treeNode.val + " "); } } /** * 測試 * * @param args */ public static void main(String[] args) { String[] preOrder = {"A", "B", "D", "E", "G", "C", "F", "H"}; String[] inOrder = {"D", "B", "G", "E", "A", "C", "H", "F"}; BTree bTree = new BTree(); TreeNode treeNode = bTree.buildTree(preOrder, inOrder); System.out.println("二叉樹:" + treeNode); System.out.println("后續遍歷:"); bTree.postOrder(treeNode); } /** * 二叉樹對象 */ private class TreeNode { String val; //節點數據 TreeNode left; //左節點 TreeNode right; //右節點  TreeNode() { } TreeNode(String val) { this.val = val; } TreeNode(String val, TreeNode left, TreeNode right) { this.val = val; this.left = left; this.right = right; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(val); sb.append(","); sb.append(left); sb.append(","); sb.append(right); return sb.toString(); } } }

 

  運行結果:

二叉樹:A,B,D,null,null,E,G,null,null,null,C,null,F,H,null,null,null 后續遍歷: D G E B H F C A 

 

          


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM