JAVA笔记

二叉查找树的删除节点

二叉查找树的一般操作中最复杂的,虽然删除节点对于人们来收很不友好,但是在很多树中应用又非常广泛。
删除节点的一般思想:
1.找到要删除的节点
2.删除节点
3.用后面的节点替补已删除的节点。

在二叉查找树中删除节点要考虑三种情况:
1.该节点是叶节点(没有子节点)
2.该节点有一个叶子节点
3.该节点有两个叶子节点
以上三种情况是越来越复杂。

public boolean delete(int key) {
	    Node current = root;		//要删除的节点
        Node parent = root;     	//要删除节点的父节点
        boolean isLeftChild = true;	//标志删除节点为左子树还是右子树


        //通过while循环找到要删除的节点
        while (current.iData != key) {
            parent = current;
            if (key < current.iData) {
                isLeftChild = true;
                current = current.leftChild;
            } else {
                isLeftChild = false;
                current = current.RightChild;
            }
            if (current == null)
                return false;//如果整棵树都为空,则退出循环
        }
        //以上代码为找到节点要删除的节点。
        //这样就清空了整棵树。否则就把父节点的leftLChild或者RightChild字段置为空,
      
        //情况一:删除没有子节点的节点
        //先检查它是否真的没有子节点,还要检查它是否根节点,如果是根就要把它置为空。
        if (current.leftChild == null && current.RightChild == null) {
            if (current == root)//如果要删除节点为根节点
                root = null;//整棵树都置空

            else if (isLeftChild)//要删除节点为左节点
                parent.leftChild = null;
                
            else
             parent.RightChild = null;//要删除节点为右节点
        } //到此没有节点的已经写完


        //情况二:删除只有一个节点的情况
        else if (current.RightChild == null)//删除节点只有左节点
            if (current == root)
                root = current.leftChild;
            else if (isLeftChild)  //左节点,但不是根节点
                parent.leftChild = current.leftChild;
            else
                parent.RightChild = current.leftChild;
                
        else if (current.leftChild == null)//删除节点只有右节点
            if (current == root)
                root = current.RightChild;
            else if (isLeftChild)
                parent.leftChild = current.RightChild;
            else
                parent.RightChild = current.RightChild;

            //情况三:删除有两个子节点节点,
            //删除有两个子节点的情况,问题关键是删除的节点后,应该用哪一个节点来替补被删除的节点呢?
          	//答案是:用右子树的最小节点来替补,这就保证了二叉查找树的原本特性
          else{
                Node successor=getSuccessor(current);
                if(current==root)
                    root=successor;
                else if(isLeftChild)
                    parent.leftChild=successor;
                else
                    parent.RightChild=successor;
                successor.leftChild=current.leftChild;
        }
            return true;
    }

    //寻找右子树的最小节点
    private Node getSuccessor(Node delNode){
        Node successorParent=delNode; 	//delNode是要删除的节点
        Node successor=delNode;         //successor为记录找到的右子树的最小节点
        Node current=delNode.RightChild; //current记录删除节点的右子树
        //二叉查找树的特性:最左节点为最小值,最右节点为最大值
        //左节点不为空,直走找到右子树的最左节点-->那个就是右子树的最小值
        while(current!=null){
            successorParent=successor;
            successor=current;
            current=current.leftChild;
        }
        //还要判断右子树最小节点是否等于删除节点的右节点
        if(successor!=delNode.RightChild){
            //如果最小节点不是要删除节点的右孩子,就要处理最小节点的右孩子节点
            successorParent.leftChild=successor.RightChild;
            successor.RightChild=delNode.RightChild;
        }
        return successor;
    }

下图为删除只有一个节点的情况,左右节点分别删除的情况。
在这里插入图片描述
好了,以上为二叉查找树的删除部分内容,动手试试吧!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值