删除节点分为三种情况:
1.删除的节点是叶子节点无子节点,此时只需要将父节点对它的引用设置为空即可。
2.删除的节点只有一个子节点,即只要左子节点或只有右子节点。此时只需要将待删除节点的父节点属性的引用指向待删除节点的子节点即可。
3.删除的节点左右子节点都不为空,此时需要找到一个替换的节点来替换待删除的节点即可。替换节点一般位于待删除节点的右子节点的最左的子节点。
代码实现:
//删除节点
public boolean deleteNode(int value){
//查找节点
Node current=rootNode;
Node parent=rootNode;
boolean isLeft=true;
while (current.getData()!=value){
parent=current;
if (value>current.getData()){
current=current.getRightNode();
isLeft=false;
}else{
current=current.getLeftNode();
isLeft=true;
}
if (current==null){
return false;
}
}
//当删除的节点是叶子节点
if (current.getLeftNode()==null && current.getRightNode()==null){
if (current==rootNode){
rootNode=null;
}else if (isLeft==true){
parent.setLeftNode(null);
}else {
parent.setRightNode(null);
}
//删除的节点只存在左子节点
}else if (current.getRightNode()==null){
//判断删除的节点是父节点的左节点还是右节点
if (current==rootNode){
rootNode=current.getLeftNode();
}else if (isLeft==true){
parent.setLeftNode(current.getLeftNode());
}else{
parent.setRightNode(current.getLeftNode());
}
//删除的节点只存在右子节点
}else if (current.getLeftNode()==null){
//判断删除的节点是父节点的左节点还是右节点
if (current==rootNode){
rootNode=current.getRightNode();
}else if (isLeft==true){
parent.setLeftNode(current.getRightNode());
}else{
parent.setRightNode(current.getRightNode());
}
//待删除节点存在左右子节点
}else{
Node replaceNode = getReplaceNode(current);
if (current==rootNode){
replaceNode.setLeftNode(current.getLeftNode());
replaceNode.setRightNode(current.getRightNode());
rootNode=replaceNode;
}else if (isLeft==true){
parent.setLeftNode(replaceNode);
replaceNode.setLeftNode(current.getLeftNode());
replaceNode.setRightNode(current.getRightNode());
}else{
parent.setRightNode(replaceNode);
replaceNode.setRightNode(current.getRightNode());
replaceNode.setLeftNode(current.getLeftNode());
}
}
return true;
}
//根据要删除的节点,在树中寻找替换节点
// 替换节点为待删除节点的右节点的最左的子节点
public Node getReplaceNode(Node node){
Node current=node.getRightNode();
Node parent=node;
while (current.getLeftNode()!=null){
parent=current;
current=current.getLeftNode();
}
//当替换节点不存在右子节点,根据替换节点的位置设置父节点的左右节点的属性
if (current.getRightNode()==null){
if (parent==node){
parent.setRightNode(null);
}else{
parent.setLeftNode(null);
}
//当替换节点存在右子节点,需要将右子节点连接到替换节点的父节点的左子节点或者右子节点中
//当替换节点为待删除节点为右节点时,替换节点的右子节点连接到父节点的右边,反之,左边
}else{
if (parent==node){
parent.setRightNode(current.getRightNode());
}else {
parent.setLeftNode(current.getRightNode());
}
}
System.out.println("替换节点为:"+ current.getData());
return current;
}