删除的所有情况
删除的是叶子节点
(1)该叶子节点不是根节点
此时将父节点的left或right修改为null即可(直接将节点删除)。
(2)是根节点
将根节点root修改为null即可。
删除的是度为1的节点
(1)该节点不是根节点
既然要删掉13,势必要找到代替的节点与10相连,此时直接使用13唯一的子节点12来替代,就可以不破坏二叉树中原有的顺序。
删除后:
(2)是根节点
此时直接将根节点指向其子节点即可。
删除的是度为2的节点
依旧找到后继节点15,此时将9修改为15,并且删除后继节点15即可,而由于后继节点一定是度为0或1的节点,删除操作同上所示。
具体实现
/**
* 删除对应元素元素
* @param element
*/
public void remove(E element){
remove(node(element));
}
/**
* 删除对应的节点
* @param node
*/
private void remove(Node<E> node){
if(null==node)return;
size--;
if(node.hasTwoChildren()) {//有两个叶子节点,使用后继节点代替
Node<E> successor = successor(node);//后继节点
node.element = successor.element;//替换元素值
node=successor;//将node指向待删除元素
}
//对指向的节点进行删除
Node<E> replacement=node.left!=null?node.left:node.right;
if(replacement==null){//叶子节点
if(root==node)//node是根节点
root=null;
else if(node==node.parent.left)
node.parent.left=null;
else
node.parent.right=null;
}else{//非叶子节点
replacement.parent=node.parent;//更改父节点
if(root==node) {//如果node是根节点
root = replacement;
}else if(node==node.parent.left)
node.parent.left=replacement;
else
node.parent.right=replacement;
}
}
/**
* 查找到元素为element的节点
* @param element
*/
private Node<E> node(E element){
Node<E> node=root;
while(null!=node){
int cmp=compare(element,node.element);
if(cmp==0)return node;
else if(cmp<0)node=node.left;
else node=node.right;
}
return null;
}