参考了Java里的TreeMap的实现,觉得里面的删除结点的操作很值得一读!所以记录下来:
public Object delNode(int k){
Node p=search(k);//找出要删除的结点
if(p==null){
return null;
}
int oldValue=p.key;
if(p.left!=null&&p.right!=null){//先处理左、右子树都不为空的情况
Node s=findMin(p.right);//找出右子树的最小值,这个也是要删除的结点,它的值copy到p中,这样最终就是要删除右子树的最小值结点,而且该结点是肯定无左子树的
p.key=s.key;
p=s;//p指向右子树的最小值
}
Node replacement=p.left!=null?p.left:p.right;//经过了上面对左右子树均非空的处理,这里就可以惟一确定了(因为已经确定了要删除的结点只可能是左、右子树中最多只有一个非空),精妙!
if(replacement!=null){//要删除的结点有左或者右子树的情况
replacement.parent=p.parent;
if(p.parent==null){
root=replacement;
}else if(p==p.parent.left){
p.parent.left=replacement;
}else{
p.parent.right=replacement;
}
p.left=p.right=p.parent=null;
}else if(p.parent==null){//要删除的结点为根结点的情况,且无左右子树,即整棵树只有一个根结点
root=null;
}else{//要删除的结点是叶子结点
if(p.parent!=null){
if(p==p.parent.left){
p.parent.left=null;
}else if(p==p.parent.right){
p.parent.right=null;
}
p.parent=null;
}
}
return oldValue;
}
public Node search(int k){
Node r=root;
while(r!=null){
if(k<r.key){
r=r.left;
}else if(k>r.key){
r=r.right;
}else{
return r;
}
}
return null;
}
public Node findMin(Node r){
if(r==null){
return null;
}
Node node=r;
while(node.left!=null){
node=node.left;
}
return node;
}