根據遍歷結果構造二叉樹
阿新 • • 發佈:2021-02-14
技術標籤:資料結構與演算法
根據遍歷結果構造二叉樹
根據遍歷結果構造二叉樹
只能通過前序和中序,或者中序和後續唯一確認一棵二叉樹,而前序和後序無法做到。
1)前序和中序結果倒推二叉樹
思路:
先根據前序結果,找到根節點
找到中序結果中根節點的位置,確認左右子樹的個數
切出左子樹的前序和中序結果,再按照此方法推進,
直到推匯出葉子節點的位置,反倒推出整棵樹。
0 1 2 3 4
1 2 3 4 5
3 4 2 1 5
根節點在中序中的位置是3 (左子樹的大小)
leftSize = 3
左子樹的前序和中序
切分的區間是左閉右開
2 3 4 [1,leftSize+1)
3 4 2 [0,leftSize)
右子樹的前序和中序
5 [leftSize+1,end)
5 [leftSize+1,end)
public static TreeNode buildTree(int[] preOrder, int[] inOrder) { // 遞迴出口 if (preOrder.length == 0) return null; // 在前序結果中 找到根節點 int rootValue = preOrder[0]; TreeNode root = new TreeNode(rootValue); // 查詢根節點在中序結果中的位置 int leftSize = find(inOrder, rootValue); // 切分出左子樹的前序和中序結果 // 使用 Arrays.copyOfRange方法 三個引數 原始陣列 起始位置 終止位置 // [起始位置,終止位置) // // 2 3 4 [1,leftSize+1) // // 3 4 2 [0,leftSize) int[] leftPreOrder = Arrays.copyOfRange(preOrder, 1, leftSize + 1); int[] leftInOrder = Arrays.copyOfRange(inOrder, 0, leftSize); root.left = buildTree(leftPreOrder, leftInOrder); // 切分出右子樹的前序和中序結果 // // 5 [leftSize+1,end) // 5 [leftSize+1,end) int[] rightPreOrder = Arrays.copyOfRange(preOrder, leftSize + 1, preOrder.length); int[] rightInOrder = Arrays.copyOfRange(inOrder, leftSize + 1, inOrder.length); root.right = buildTree(rightPreOrder, rightInOrder); return root; } public static int find(int[] array, int value) { for (int i = 0; i < array.length; i++) { if (array[i] == value) { return i; } } return -1; }
2)中序和後序結果倒推二叉樹
0 1 2 3 4
3 4 2 1 5
4 3 2 5 1
根節點在中序中的位置是3 (左子樹的大小)
leftSize = 3
左子樹的中序和後序
切分的區間是左閉右開
3 4 5 [0,leftSize)
4 3 2 [0,leftSize)
右子樹的中序和後序
5 [leftSize+1,end)
5 [leftSize,end-1)
public static TreeNode buildTree1(int[] inOrder, int[] postOrder) { // 遞迴出口 if (inOrder.length == 0 || postOrder.length == 0) return null; // 在前序結果中 找到根節點 int rootValue = postOrder[postOrder.length - 1]; TreeNode root = new TreeNode(rootValue); // 查詢根節點在中序結果中的位置 int leftSize = find(inOrder, rootValue); // 切分出左子樹的中序和後序結果 // 使用 Arrays.copyOfRange方法 三個引數 原始陣列 起始位置 終止位置 // [起始位置,終止位置) // // 3 4 5 [0,leftSize) // 4 3 2 [0,leftSize) int[] leftInOrder = Arrays.copyOfRange(inOrder, 0, leftSize); int[] leftPostOrder = Arrays.copyOfRange(postOrder, 0, leftSize); root.left = buildTree1(leftInOrder, leftPostOrder); // 切分出右子樹的中序和後序結果 // // 5 [leftSize+1,end) // 5 [leftSize,end-1) int[] rightInOrder = Arrays.copyOfRange(inOrder, leftSize + 1, inOrder.length); int[] rightPostOrder = Arrays.copyOfRange(postOrder, leftSize, postOrder.length - 1); root.right = buildTree1(rightInOrder, rightPostOrder); return root; }