重構二叉樹:
1. 一般題目會給定前序遍歷(或后序遍歷)、中序遍歷,讓你重構二叉樹,輸出另一種遍歷。如果沒有給定中序遍歷則無法重構二叉樹。
這里先學習簡單的已知前序、中序求后序遍歷:
首先我們得知道幾種遍歷二叉樹的特點:
1)前序遍歷二叉樹:首先遍歷二叉樹的根節點,然后遍歷左子樹,然后遍歷右子樹。
2)中序遍歷二叉樹:首先遍歷左子樹,然后根節點,然后遍歷右子樹。
3)后序遍歷二叉樹:首先遍歷左子樹,然后右子樹,最后根節點。
由上得出:1. 跟定的前序遍歷序列中,第一個數據就是根節點。
2. 給定的中序遍歷序列中,找到從前序遍歷中確定的根節點,然后將中序遍歷的序列根據這個節點分成兩部分,根節點前半部分,是整個二叉樹的左子樹,后半部分是整個二叉樹的右子樹。
代碼:
// 二叉樹節點定義class TreeNode{ TreeNode left; TreeNode right; int value ; public TreeNode(int value) { this.value = value; }
public TreeNode(){
}
}
// 首先過濾非法,判斷給定的前序中序序列是否合法 public TreeNode reBinaryTree(TreeNode [] preOrder,TreeNode [] inOrder){ // 判斷序列長度是否合法 int preLen = preOrder.length; int inLen = inOrder.length; if(preLen==0||inLen==0){ return null; } return ctBinaryTree(preOrder,inOrder,0,preLen-1,0,inLen-1); }
// 然后調用構造二叉樹的方法遞歸構造二叉樹 public TreeNode ctBinaryTree(TreeNode [] preOrder, TreeNode [] inOrder ,int preStart, int preEnd, int inStart, int inEnd){ // 根據前序遍歷序列中第一個節點(根節點)構建二叉樹根節點。 TreeNode tree = new Tree(preOrder[preStart]); // 從中序遍歷中找到根節點,然后划分左右子樹長度 int root = 0; for(root = inStart;root < inEnd;root++){ if(preOrder[preStart]==inOrder[root]){ break; } int leftLen = root - inStart; int rightLen = inEnd - root; // 遞歸構造二叉樹 if(leftLen > 0){ tree.left = ctBinartTree(preOrder , inOrder , preStart+1,preStart+leftLen,inStart,root-1); } if(rightLen > 0){ tree.right = ctBinaryTree(preOrder , inOrder , preStart+1+leftLen,root+1,inEnd); } return tree; } }