二叉查找树(Binary Search Tree): 它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
树的节点的定义:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
1 插入
/*
* 二叉搜索树的插入 插入的时候如果节点为空,则生成一个新的节点,并将连接指向它 如果被插入的值小于根节点的值,则继续在左子树中插入
* 否则继续在右子树中插入
*/
public TreeNode insert(int x, TreeNode T) {
if (T == null) {
T = new TreeNode(x);
T.left = null;
T.right = null;
} else {
if (x < T.getVal()) {
T.left = insert(x, T.left);
} else if (x > T.getVal()) {
T.right = insert(x, T.right);
}
}
return T;
}
2 删除最大值、最小值
/*
* 删除二叉搜索树中的最小值 因为最小值肯定是在左子树里, 直到遇到一个空指针, 然后将指向该指针的连接指向该指针的右指针
*/
public TreeNode deleteMin(TreeNode root) {
if (root.left == null) {
return root.right;
}
root.left = deleteMin(root.left);
return root;
}
/*
* 删除二叉搜索树的最大值 最大值在右子树里,所以一直往右子树走,直到遇到空连接,如果该节点的左子树不为空,则返回左子树, 如果为空则直接返回空
* 或者也可以直接返回左子树
*/
public TreeNode deleteMax(TreeNode root) {
if (root.right == null) {
return root.left;
}
root.right = deleteMax(root.right);
return root;
}
3 查找最大值和最小值
// 查找二叉搜索树中的最小值节点,一直往左子树中找
public TreeNode findMin(TreeNode node) {
if (node == null) {
return null;
} else {
if (node.left == null) {
return node;
} else {
return findMin(node.left);
}
}
}
// 查找二叉搜索树中的最大值节点,一直往右子树中找
public TreeNode findMax(TreeNode node) {
if (node == null) {
return null;
} else {
if (node.right == null) {
return node;
} else {
return findMax(node.right);
}
}
}
4 删除任意节点
- 被删除的节点是叶子节点,这时候只要把这个节点删除,再把指向这个节点的父节点指针置为空就行
- 被删除的节点有左子树,或者有右子树,而且只有其中一个,那么只要把当前删除节点的父节点指向被删除节点的左子树或者右子树就行。
上面这两种情况,可以归为一类,就是不是左右子树都不为空的情况,即左子树为空,或右子树为空,以及左右子树都为空的情况。 - 被删除的节点既有左子树而且又有右子树,这时候需要把左子树的最右边的节点或者右子树最左边的节点提到被删除节点的位置,这里我找的是右子树的最小值的节点,当找到以后,有两种方案进行处理,一种是将最小值节点的值赋给要删除节点,然后再到右子树中删除那个最小节点,还有一种方案,就是我们找到最小节点以后,让最小值节点的右指针指向要被删除的节点的右子树中(该右子树已经被删除了最小节点),接着让最小值节点的左子树指向要删除节点的左子树。(这里的删除只是使没有节点指向该节点)
public TreeNode delete(TreeNode node, int x) {
if (node == null) {
System.out.println("There is no such node!");
return null;
} else {
if (x < node.getVal()) {// 当要删除节点小于当前节点的值,向左子树中,进行寻找
node.left = delete(node.left, x);
} else if (x > node.getVal()) {// 当要删除节点大于当前节点的值,向左子树中,进行寻找
node.right = delete(node.right, x);
} else { // 当要删除节点等于当前节点的值的时候,进行删除
// 当左子树和右子树都不为空的时候
if (node.left != null && node.right != null) {
/*
* TreeNode temp = node; node = findMin(temp.right); //
* 找到要删除节点右子树的最小节点 node.right = deleteMin(temp.right);
* node.left = temp.left;
*/
TreeNode temp = findMin(node.right);
node.setVal(temp.getVal());
node.right = delete(node.right, temp.getVal());
} else {
if (node.left == null) {
return node.right; // 如果左子树为空,那么直接将右子树返回
}
if (node.right == null) {
return node.left; // 如果右子树为空,那么直接将左子树返回
}
}
}
}
return node;
}