二分搜索树其他操作
删除结点操作
// 查看最大结点的值
public E MaxNum() {
return MaxNum(root).e;
}
private Node MaxNum(Node node) {
if (node.right == null) {
return node;
}
return MaxNum(node.right);
}
// 查看最小结点的值
public E MinNum() {
return MinNum(root).e;
}
private Node MinNum(Node node) {
if (node.left == null) {
return node;
}
return MinNum(node.left);
}
// 对外提供删除最大结点
public E removeMax() {
root = removeMax(root);
return MaxNum(root).e;
}
// 递归右子树找到最大结点 然后把最大结点的左子树返回给上一个结点的右节点
private Node removeMax(Node node) {
if (node.right == null) {
Node leftNode = node.left;
node.left = null;
return leftNode;
}
node.right = removeMax(node.right);
return node;
}
// 对外提供删除最小结点
public E removeMin() {
root = removeMin(root);
return MinNum(root).e;
}
// 递归左子树找到最小结点 然后把最小结点的右子树返回给上一个结点的左结点
private Node removeMin(Node node) {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
return rightNode;
}
node.left = removeMax(node.left);
return node;
}
// 删除任意结点对外提供的方法
public void remove(E e) {
root = remove(root,e);
}
private Node remove(Node node,E e) {
// 当二叉树为空 或者没有当前要删除的元素走这
if (node ==null) {
return null;
}
// 如果待删除元素比当前结点小那么走左子树
if (e.compareTo(node.e) < 0) {
// 此处是当前结点接收改变后的左子树
node.left =remove(node.left,e);
return node;
// 如果待删除元素比当前结点大那么走右子树
}else if (e.compareTo(node.e) > 0) {
// 此处是当前结点接收改变后的右子树
node.right =remove(node.right,e);
return node;
// 此时是找到了要删除的结点
}else {
// 如果待删除结点的左子树为空 那么操作类似删除最小结点
if (node.left == null) {
Node rightNode =node.right;
node.right=null;
return rightNode;
}
// 如果待删除结点的右子树为空 那么操作类似删除最大结点
if (node.right == null) {
Node leftNode =node.left;
node.left=null;
return leftNode;
}
// 如果都不为空说明左右子树都存在 那么为了满足二分搜索树性质
// 左子树都小于当前结点 右子树都大于当前结点
// 此时需要把右子树最小的结点拿出来作为此结点
// 此结点右子树 =原右子树删除最小结点
// 此时结点的左子树 =原左子树
Node success = MinNum(node.right);
success.right =removeMin(node.right);
success.left =node.left;
return success;
}
}