目錄
題目:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如,輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建如圖2.6所示的二叉樹並輸出它的頭節點。二叉樹節點的定義如下:stuct BinaryTreeNode {
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_right;
}
思路:
在二叉樹的前序遍歷序列中,第一個數字總是樹的根節點的值。但在中序遍歷序列中,根節點的值在序列的中間,左子樹的節點的值位於根節點的值的左邊,而右子樹的節點的值位於根節點的值的右邊。因此我們需要掃描中序遍歷序列,才能找到根節點的值。步驟:
1.前序遍歷序列的第一個數字1就是根節點的值。掃描中序遍歷序列,就能確定根節點的值的位置。根據中序遍歷的特點,在根節點的值1前面的3個數字都是左子樹的值,位於1後面的數字都是右子樹節點的值。2.由於在中序遍歷序列中,有3個數字是左子樹節點的值,因此左子樹共有3個左子節點。同樣,在前序遍歷序列中,根節點後面的3個數字就是3個左子樹的節點的值,再後面的所有數字都是右子樹節點的值。這樣我們就在前序遍歷和中序遍歷兩個序列中分別找到了左、右子樹對應的子序列。
3.既然我們已經分別找到了左、右子樹的前序遍歷序列和中序遍歷序列,我們可以用同樣的方法分別構建左、右子樹。也就說,接下來的事情可以用遞歸的方法去完成。
代碼:
package test;
public class BinaryTreeNode {
public static void main(String[] args) {
int[] pre = {1, 2, 4, 7, 3, 5, 6, 8};
int[] in = {4, 7, 2, 1, 5, 3, 8, 6};
TreeNode root = reConstructBinaryTree(pre, in);
printTree(root);
}
private static void printTree(TreeNode root) {
if(root != null) {
printTree(root.left);
System.out.println(root.value);
printTree(root.right);
}
}
public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
//對輸入數據進行校驗
if(pre == null || in == null || pre.length != in.length)
return null;
return construct(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
private static TreeNode construct(int[] pre, int ps, int pe, int[] in, int is, int ie) {
//5.遞歸結束條件
if(ps > pe)
return null;
//1.獲取根節點
int root = pre[ps];
//2.掃描中序遍歷序列,確定根節點的位置
int index = is;
while(index <= ie && root != in[index])
index++;
//3.創建根節點
TreeNode node = new TreeNode(root);
//4.創建左右子節點
node.left = construct(pre, ps + 1, ps + index - is, in, is, index - 1);
node.right = construct(pre, ps + index - is + 1, pe, in, index + 1, ie);
return node;
}
static class TreeNode {
int value;
TreeNode left;
TreeNode right;
public TreeNode(int value) {
this.value = value;
}
}
}