递归还原思路:
- 后续遍历的特点,后续数组的最后一个元素一定是根节点
- 二叉搜索树的特点,左子树的关键字均小于根节点,右子树的关键字均大于根节点
- 根据
1
和2
中的特点我们可以得出如下结论:任意给定一个后续遍历数组,我们一定能找到根节点,通过从第一个位置开始遍历该后续数组,当我们找到第一个关键字大于根节点时,该位置就是根节点右子树的起始位置,相应的该位置也就是根节点左子树的结束位置。 - 根据如上阐述,我们可以得出如下递归还原算法:
public class BST {
public class Node {
public int key;
public Node left;
public Node right;
public Node (int key, Node left, Node right) {
this.key = key;
this.left = left;
this.right = right;
}
public int getKey() {
return key;
}
}
public Node postArrayToBST(int[] postArray, int start, int end) {
if (start > end)
return null;
Node root = new Node(postArray[end], null, null);
int rightStart = start - 1;
for (int i = start; i < end; i++) {
if (postArray[i] < root.getKey())
rightStart = i;
}
root.left = postArrayToBST(postArray, start, rightStart);
root.right = postArrayToBST(postArray, rightStart + 1, end - 1);
return root;
}
public void preOrderTraverse(Node root) {
if (root != null) {
System.out.println(root.key);
preOrderTraverse(root.left);
preOrderTraverse(root.right);
}
}
public static void main(String[] args) {
int[] postArray = new int[]{1, 2, 3, 4};
BST bst = new BST();
Node root = bst.postArrayToBST(postArray, 0, postArray.length - 1);
bst.preOrderTraverse(root);
}
}