二叉搜索树(Binary Search Tree)—— 二叉树中非常经典的一种数据结构。
满足条件
左子树的所有节点小于root;
右子树的所有节点大于root;
节点值不能重复。
缺陷
Search Best case: O(logN),Worst case:O(N)
Insert Best case: O(logN),Worst case:O(N)
当BST不平衡时(N为BST中节点的数量),极端情况下类似于单链表,search和insert操作的时间复杂度均为O(N)。
Operation
public void insert(T v); // 将新的节点插入BST
public boolean search(T v); // 查找当前BST中是否有节点的值为v
public void delete(T v); // 删除BST中含有v的节点
public int getSize(); // 返回BST节点数量
java代码
以如下BST为例测试上述操作的正确性
BST.java
public class BST<T extends Comparable<T>> {
private BSTNode root;
private int size;
private class BSTNode {
private T value;
private BSTNode left;
private BSTNode right;
BSTNode(T value) {
this.value = value;
}
}
BST(T value) {
this.root = new BSTNode(value);
this.size += 1;
}
/**
* 将新的节点插入BST
*/
public void insert(T v) {
root = insertHelper(root, v);
this.size += 1;
}
private BSTNode insertHelper(BSTNode curNode, T value) {
if (curNode == null) {
return new BSTNode(value);
} else if (curNode.value.compareTo(value) > 0) {
curNode.left = insertHelper(curNode.left, value);
} else if (curNode.value.compareTo(value) < 0) {
curNode.right = insertHelper(curNode.right, value);
}
return curNode;
}
/**
* 查找当前BST中是否有节点的值为v
*/
public boolean search(T v) {
return searchHelper(root, v);
}
private boolean searchHelper(BSTNode curNode, T value) {
if (curNode == null) {
return false;
} else if (curNode.value.compareTo(value) == 0) {
return true;
} else if (curNode.value.compareTo(value) > 0) {
return searchHelper(curNode.left, value);
} else {
return searchHelper(curNode.right, value);
}
}
/**
* 删除BST中含有v的节点
* 如果该节点为叶子节点,直接删除
* 如果该节点有一个child节点,删除该节点后return child节点
* 如果该节点有两个child节点, 将该节点和其右子树最左边的节点/左子树最右边的节点进行交换
* 继续删除该节点
*/
public void delete(T v) {
root = deleteHelper(root, v);
}
private BSTNode deleteHelper(BSTNode curNode, T value) {
if (curNode == null) {
return null;
} else if (curNode.value.compareTo(value) > 0) {
curNode.left = deleteHelper(curNode.left, value);
} else if (curNode.value.compareTo(value) < 0) {
curNode.right = deleteHelper(curNode.right, value);
} else {
if (checkLeaf(curNode)) {
this.size -= 1;
return null;
} else if (checkOnlyLeftChild(curNode)) {
this.size -= 1;
return curNode.left;
} else if (checkOnlyRightChild(curNode)) {
this.size -= 1;
return curNode.right;
} else {
BSTNode successor = getSuccessor(curNode);
curNode.value = successor.value;
successor.value = value;
curNode.right = deleteHelper(curNode.right, value);
}
}
return curNode;
}
/**
* 找到当前节点右子树最左边的节点(successor)并返回
*/
private BSTNode getSuccessor(BSTNode curNode) {
return getSuccessorHelper(curNode.right);
}
private BSTNode getSuccessorHelper(BSTNode curNode) {
if (curNode.left == null) {
return curNode;
} else {
return getSuccessorHelper(curNode.left);
}
}
private boolean checkLeaf(BSTNode curNode) {
return curNode.left == null && curNode.right == null;
}
private boolean checkOnlyLeftChild(BSTNode curNode) {
return curNode.left != null && curNode.right == null;
}
private boolean checkOnlyRightChild(BSTNode curNode) {
return curNode.right != null && curNode.left == null;
}
public int getSize() {
return size;
}
}
Test.java
public class Test {
public static void main(String[] args) {
BST<Integer> test = new BST<>(7);
test.insert(3);
test.insert(15);
test.insert(1);
test.insert(6);
test.insert(8);
test.insert(9);
test.insert(4);
System.out.println(test.getSize()); // 8
System.out.println(test.search(1)); // 删除叶子节点
test.delete(1);
System.out.println(test.search(1));
System.out.println(test.search(6)); // 删除只有一个child的节点
test.delete(6);
System.out.println(test.search(6));
System.out.println(test.search(7)); // 删除有两个child的节点
test.delete(7);
System.out.println(test.search(7));
System.out.println(test.getSize()); // 5
}
}