删除一个节点就是看有没有其孩子节点可以代替它,一般的可以找后继节点(右子树最小值)或前继节点(左子树的最大值)
理清楚思路: d是删除的点,左右都有孩子,s是d的右孩子最小的点
1. 找d的后继节点s
2. s.right = delMin(d.right),在d的右子树删除最小的并返回其子树的根节点
3. s.left = d.left
4. 删除d, s是新树的子树的根
主要是二种情况:
当左右子树有一个不存在,跟前面的删除最大最小值一样。
当左右都存在时,就是得找后继节点或前继节点了~
public void remove(Key key){
root = remove(root, key);
}
private Node remove(Node node, Key key){
if(node == null) return null;
if(key.compareTo(node.key) < 0){
node.left = remove(node.left, key);
return node;
}else if(key.compareTo(node.key) > 0){
node.right = remove(node.right, key);
return node;
}else{ //找到了这个点 key == node.key
//待删除节点左子树为空
if(node.left == null){
Node rightNode = node.right;
node.right = null;
count --;
return rightNode;
}
//待删除的节点右子树为空
if(node.right == null){
Node leftNode = node.left;
node.left = null;
count --;
return leftNode;
}
//待删除的左右子树都不为空, 这里找待删除节点右子树的最小节点
Node successor = minimun(node.right);
count ++;
successor.right = removeMin(node.right);
successor.left = node.left;
node.left = node.right = null;
count --;
return successor;
}
}