Java 可以根據給定的前序遍歷和中序遍歷構造二叉樹。首先,讓我們看看什么是前序遍歷和中序遍歷。
前序遍歷是將根節點排在子節點之前進行遍歷的方式。其中,“根節點”是指一棵二叉樹的根,而“子節點”是指一個節點的左子樹或右子樹。因此,前序遍歷的順序為:根節點,左子樹,右子樹。
1 / \ 2 3 / \ 4 5
如上圖所示,如果以 1 為根,那么先訪問 1,再訪問 2,最后訪問 3、4、5。
中序遍歷是將根節點排在子節點之間進行遍歷的方式,因此中序遍歷的順序為:左子樹,根節點,右子樹。
4 / \ 2 5 \ 3
如上圖所示,如果以 4 為根,那么先訪問 2,再訪問 3,最后訪問 5。
現在回到 Java 中如何根據前序遍歷和中序遍歷構造二叉樹。我們可以按照以下步驟進行:
1. 從前序遍歷序列中取出根節點。
1 / \
2. 在中序遍歷序列中找到根節點所在的位置。
4 / \ 2 5 \ 3
3. 根據中序遍歷序列中根節點所在的位置,可以知道左子樹的節點個數和右子樹的節點個數。
1 / \ /__\ / \ [2 3] [4 5]
4. 根據左子樹和右子樹的節點個數,可以在前序遍歷序列中找到左子樹和右子樹的范圍。
[1] [2] [3] [4] [5] 先序:[1] [2] [3] [4] [5] / 中序:[2] [3] [4] [1] [5] \ 后序:[3] [2] [4] [5] [1]
5. 遞歸構造左子樹和右子樹,然后返回根節點。
1 / \ 2 3 / \ 4 5
以上就是根據前序遍歷和中序遍歷構造二叉樹的過程。使用 Java 代碼實現時,可以使用遞歸函數來實現,在每一次遞歸返回時,返回當前子樹的根節點即可。
public TreeNode buildTree(int[] preorder, int[] inorder) { if(preorder == null || inorder == null || preorder.length != inorder.length) { return null; } return buildTreeSub(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode buildTreeSub(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { if(preStart >preEnd) { return null; } int rootValue = preorder[preStart]; int rootIndex = inStart; while(rootIndex<= inEnd && inorder[rootIndex] != rootValue) { rootIndex++; } int leftSize = rootIndex - inStart; TreeNode root = new TreeNode(rootValue); root.left = buildTreeSub(preorder, preStart + 1, preStart + leftSize, inorder, inStart, rootIndex - 1); root.right = buildTreeSub(preorder, preStart + leftSize + 1, preEnd, inorder, rootIndex + 1, inEnd); return root; }