package cn.dzp.flyroc.offer; import java.util.Arrays; public class TreeNodeDemo { /*題目描述:輸入某二叉樹的前序遍歷的結果,請重建出該二叉樹 * 假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。 * 例如:輸入前序遍歷的序列{1,2,4,7,3,5,6,8}和 * 中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回*/ /*思路:先找出根節點,而後利用遞歸方法構造二叉樹 * 在二叉樹的前序遍歷序列中,第一個數字老是樹的根結點的值。 * 但在中序遍歷序列中,根結點的值在序列的中間, * 左子樹的結點的值位於根結點的值的左邊, * 而右子樹的結點的值位於根結點的值的右邊。 * 所以咱們須要掃描中序遍歷序列,才能找到根結點的值。*/ /*先序遍歷的第一個元素爲根節點,在中序遍歷中找到這個根節點,從而能夠將中序遍歷分爲左右兩個部分, 左邊部分爲左子樹的中序遍歷,右邊部分爲右子樹的中序遍歷,進而也能夠將先序遍歷除第一個元素之外的剩餘部分分爲兩個部分, 第一個部分爲左子樹的先序遍歷,第二個部分爲右子樹的先序遍歷。 由上述分析結果,能夠遞歸調用構建函數,根據左子樹、右子樹的先序、中序遍歷重建左、右子樹*/ //代碼實現 public static class TreeNode{ //構建樹的節點類 int val; TreeNode left; //構建左子樹 TreeNode right; //構建右子樹 //構造方法 TreeNode(int x){ val = x; } //重寫toString方法 public String toString() { return "["+val+"——>"+left+" "+right+"]"; } } //重建二叉樹 public static TreeNode reConstructBinaryTree(int[] pre, int[] in){ if (pre == null || in == null){ //判斷前序序列和中序序列是否爲空 return null; } if (pre.length == 0 || in.length == 0){ //判斷前序序列和中序序列的長度是否爲0 return null; } if (pre.length != in.length){ //判斷前序序列的長度是否等於中序序列 return null; } TreeNode root = new TreeNode(pre[0]); //構建根節點 for (int i = 0; i < pre.length; i++){ //遍歷前序序列 if (pre[0] == in[i]){ //判斷前序序列的根節點(第一個節點)是否與中序序列的其中一個節點相同 root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), //將數組pre從1開始複製直到i+1 Arrays.copyOfRange(in, 0, i)); //構建左子樹; //將數組in從0開始複製到i root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), //將數組從i+1開始複製到數組的最後一個元素 Arrays.copyOfRange(in, i+1, pre.length)); //構建右子樹 } } return root; } public static void main(String[] args){ //前序序列 int[] pre = {1,2,4,7,3,5,6,8}; System.out.println("這是前序序列:"+Arrays.toString(pre)); //中序序列 int[] in = {4,7,2,1,5,3,8,6}; System.out.println("這是中序序列:"+Arrays.toString(in)); TreeNode treeNode = reConstructBinaryTree(pre, in); System.out.println("重建後的序列:"+treeNode); } }