//保存当前节点 Node parent=root;//保存当前节点父节点 boolean isLeft=true;//记录是否是左几点 //定位到将被删除的节点 while(key!=curr.key){ if(key<=curr.key){ isLeft=true;//经过左节点 if(curr.left!=null){ parent=curr; curr=curr.left; } }else{ isLeft=false;//经过右节点 if(curr.right!=null){ parent=curr; curr=curr.right; } } if(curr==null){ return false; } }
if(curr.left==null&&curr.right==null){ if(curr==root){ root=null; }else if(isLeft){ parent.left=null; }else{ parent.right=null; } }
if(curr.right==null){ if(curr==root){ root=root.left; }else if(isLeft){ parent.left=curr.left; }else{ parent.right=curr.left; } }当被删除的节点只有一个孩子时,就只需要用它的孩子节点,把它自己给替换下去。具体的还是跟上面一样,需要分三种情况
if(curr.left==null){ if(curr==root){ root=root.right; }else if(isLeft){ parent.left=curr.right; }else{ parent.right=curr.right; } }
public Node getSuccessor(Node delNode){ //参数为被删除的节点 //定义一个当前节点的引用,直接让往下走一步,走到被删除节点的右节点 Node curr=delNode.right; Node successor=curr; //用来指向中级后续节点 Node sucParent=null; //用来指向中级后续节点的父节点 while(curr!=null){ sucParent=successor; successor=curr; curr=curr.left; } //循环停止,中级后续节点被找出 if(successor!=delNode.right){ //将后继节点的子节点(只可能有右节点)替补到后继节点的位置上 sucParent.left=successor.right; //将被删除的右孩子连接到后继节点的右节点上 successor.right=delNode.right; //将被删除的左孩子连接到后继节点的右节点上(就是用后继节点替换掉被删除的节点) } return successor; }
由于过程比较复杂,这里用图来表示
删除节点的完成代码:
/** * 删除节点 * @param key */ public boolean delete(int key){ Node curr=root;//保存当前节点 Node parent=root;//保存当前节点父节点 boolean isLeft=true;//记录是否是左几点 //定位到将被删除的节点 while(key!=curr.key){ if(key<=curr.key){ isLeft=true;//经过左节点 if(curr.left!=null){ parent=curr; curr=curr.left; } }else{ isLeft=false;//经过右节点 if(curr.right!=null){ parent=curr; curr=curr.right; } } if(curr==null){ return false; } } //如果被删除节点是叶子节点 if(curr.left==null&&curr.right==null){ if(curr==root){ root=null; }else if(isLeft){ parent.left=null; }else{ parent.right=null; } //如果被删除节点只有左节点 }else if(curr.right==null){ if(curr==root){ root=root.left; }else if(isLeft){ parent.left=curr.left; }else{ parent.right=curr.left; } //如果被删除节点只有右节点 }else if(curr.left==null){ if(curr==root){ root=root.right; }else if(isLeft){ parent.left=curr.right; }else{ parent.right=curr.right; } }else{ Node successor=getSuccessor(curr); //将后继节点与被删除的父节点进行连接,完成整个替换过程 if(curr==root){ root=successor; }else if(curr==parent.left){ parent.left=successor; }else{ parent.right=successor; } successor.left=curr.left; } return true; } public Node getSuccessor(Node delNode){ Node curr=delNode.right; Node successor=curr; Node sucParent=null; while(curr!=null){ sucParent=successor; successor=curr; curr=curr.left; } if(successor!=delNode.right){ //将后继节点的子节点(只可能有右节点)替补到后继节点的位置上 sucParent.left=successor.right; //将被删除的右孩子连接到后继节点的右节点上 successor.right=delNode.right; //将被删除的左孩子连接到后继节点的右节点上(就是用后继节点替换掉被删除的节点) } return successor; }
原文地址:http://blog.csdn.net/nzh1234/article/details/31076401