此篇整理关于Binary Tree已知前序遍历和中序遍历,或者已知中序遍历和后续遍历,能够唯一构造出整棵树。P.S. 已知前序遍历和后续遍历,构造的结果并不唯一。
从网上下载的一个Binary Tree的图片。三中排序方式分别是
Pre: 50 - 17 - 9 - 14 - 12 - 23 -19 - 76 - 54 - 72 - 67
In: 9 - 12 -14 -17 - 19 - 23 - 50 - 54 - 67 - 72 - 76
Post: 12 - 14 - 9 - 19 - 23 -17 - 67 - 72 - 54 - 76 -50
以前序 & 中序结合为例。以上划横线的就是root结点。根据中序能够得到(9,12,14,17,19,23)是根结点的左子树,(54,67,72,76)是右子树。
再根据前序能够确定,左子树的根结点是17,右子树的根结点是76. 依次类推。
以中序&后序结合为例。同样得到左右子树。根据后序能够确定根节点分别是17和76. 再依次类推。
相关链接:http://www.cnblogs.com/microgrape/archive/2011/05/11/2043812.html
*** 而需要注意的是前序&后序,我们同样能确定根结点,但是不能明确的唯一的Binary Tree。***
反例:任何结点只有左子树的二叉树和任何结点只有右子树的二叉树,其前序序列相同,后序序列相同,但却是两棵不同的二叉树。
1. Construct Binary Tree from Preorder and Inorder Traversal.
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
根据前序和中序来确定Binary Tree。
public class Solution {
/**
* in preorder, the first element is the root, or the parent if inorder,
* when you find the root, or the parent, left side is the left subtree,
* right side is the right subtree
*
* @param preorder
* @param inorder
* @return
*/
public TreeNode buildTree(int[] preorder, int[] inorder) {
return helper(inorder, 0, inorder.length - 1, preorder, 0, preorder.length - 1);
}
/**
* record the length of subtree in inorder array record the preorder
* traversal for the subtrees, in order to get the first element to
* construct the tree
*
* @param inorder
* @param inStart
* @param inEnd
* @param preorder
* @param preStart
* @param preEnd
* @return
*/
public TreeNode helper(int[] inorder, int inStart, int inEnd, int[] preorder, int preStart, int preEnd) {
//return edge
if (inStart > inEnd || preStart > preEnd) {
return null;
}
//in preorder, the first is the root
int val = preorder[preStart];
TreeNode root = new TreeNode(val);
int i;
int mid = 0;
//i is the start of the sub array, mid is the mid of the sub array
for (i = inStart; i <= inEnd; i++) {
if (inorder[i] == val) {
mid = i;
break;
}
}
//inleft means the number of elements in the left subtree
int inleft = mid - inStart;
//inorder: the left side of the root, preorder: the left side from preStart + 1(remove the first of the sub array) to the number of new sub array in inorder lsit
root.setLeft(helper(inorder, inStart, mid - 1, preorder, preStart + 1, preStart + inleft + 1));
//inorder: the right side of the root, preorder: from (preStart + 1/remove the first of the sub array/) + the number of the new sub array in inorder list to the end
root.setRight(helper(inorder, mid + 1, inEnd, preorder, preStart + inleft + 1, preEnd));
return root;
}
}
2. Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
根据中序和后续来确定Binary Tree。
public class Solution {
/**
* if postorder, the last will be the root, or the parent node
* if inorder, when you find the root, or the parent, left side is the left subtree, right side is the right subtree
*
* @param inorder
* @param postorder
* @return
*/
public TreeNode buildTree(int[] inorder, int[] postorder) {
return helper(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
/**
* record the length of subtree in inorder array
* record the postorder traversal for the subtrees, in order to get the last element to construct the tree
*
* @param inorder
* @param inStart
* @param inEnd
* @param postorder
* @param postStart
* @param postEnd
* @return
*/
public TreeNode helper(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {
//return edge
if (inStart > inEnd || postStart > postEnd) {
return null;
}
//in postorder, the last is the root
int val = postorder[postEnd];
TreeNode root = new TreeNode(val);
int i;
int mid = 0;
//i is the start of the sub array, mid is the mid of the sub array
for (i = inStart; i <= inEnd; i++) {
if (inorder[i] == val) {
mid = i;
break;
}
}
//inleft means the number of elements in the left subtree
int inleft = mid - inStart;
//inorder: the left side of the root, postorder: the left side until the number of new sub array in inorder lsit
root.setLeft(helper(inorder, inStart, mid - 1, postorder, postStart, postStart + inleft - 1));
//inorder: the right side of the root, postorder: from the number of the new sub array in inorder list to the end
root.setRight(helper(inorder, mid + 1, inEnd, postorder, postStart + inleft, postEnd - 1));
return root;
}
}