带有根节点的二叉排序树删除方法

原文: 二叉排序树的查找、插入、删除添加链接描述

对删除方法添加对根节点的支持

/**
     * 删除指定数据的节点
     *
     * @param data
     */
    public void delete(int data) {
        if (mRoot == null ) {  //根节点为空
            return;
        }
        //标记根节点
        boolean isRoot=false;

        //接下来该找要删除的节点了
        BinaryTreeNode deleteNode =null;
        BinaryTreeNode parent=null;


        if( mRoot.getData() == data){//判断是否是根
            deleteNode=mRoot;
            isRoot=true;

        }else{
            //在删除之前需要找到它的父亲
             parent = searchParent(data);
            if (parent == null) {        //如果父节点为空,说明这个树是空树,没法删
                return;
            }

            //接下来该找要删除的节点了
            deleteNode = search(parent, data);

            if (deleteNode == null) {    //树中找不到要删除的节点
                return;
            }


        }


        //删除节点有 4 种情况
        //1.左右子树都为空,说明是叶子节点,直接删除
        if (deleteNode.getLeftChild() == null && deleteNode.getRightChild() == null) {
            //删除节点

            if(isRoot){ //根节点置空后直接返回
                mRoot=null;
                return;
            }

            //重置父节点的孩子状态,告诉他你以后没有这个儿子了
            if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
                parent.setLeftChild(null);
            } else {
                parent.setRightChild(null);
            }


        } else if (deleteNode.getLeftChild() != null && deleteNode.getRightChild() == null) {
            //2.要删除的节点只有左子树,左子树要继承位置
            if(isRoot){
                mRoot=mRoot.getLeftChild();
                return;
            }
            if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
                parent.setLeftChild(deleteNode.getLeftChild());
            } else {
                parent.setRightChild(deleteNode.getLeftChild());
            }



        } else if (deleteNode.getRightChild() != null && deleteNode.getLeftChild() == null) {
            //3.要删除的节点只有右子树,右子树要继承位置

            if(isRoot){
                mRoot=mRoot.getRightChild();
                return;
            }

            if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
                parent.setLeftChild(deleteNode.getRightChild());
            } else {
                parent.setRightChild(deleteNode.getRightChild());
            }



        } else {
            //4.要删除的节点儿女双全,既有左子树又有右子树,需要选一个合适的节点继承,这里使用右子树中最左节点
            BinaryTreeNode copyOfDeleteNode = deleteNode;   //要删除节点的副本,指向继承节点的父节点
            BinaryTreeNode heresNode = deleteNode.getRightChild(); //要继承位置的节点,初始为要删除节点的右子树的树根
            //右子树没有左孩子了,他就是最小的,直接上位
            if (heresNode.getLeftChild() == null) {
                //上位后,兄弟变成了孩子
                heresNode.setLeftChild(deleteNode.getLeftChild());
            } else {
                //右子树有左孩子,循环找到最左的,即最小的
                while (heresNode.getLeftChild() != null) {
                    copyOfDeleteNode = heresNode;       //copyOfDeleteNode 指向继承节点的父节点
                    heresNode = heresNode.getLeftChild();
                }
                //找到了继承节点,继承节点的右子树(如果有的话)要上移一位
                copyOfDeleteNode.setLeftChild(heresNode.getRightChild());
                //继承节点先继承家业,把自己的左右孩子变成要删除节点的孩子
                heresNode.setLeftChild(deleteNode.getLeftChild());
                heresNode.setRightChild(deleteNode.getRightChild());
            }
            if(isRoot){
                mRoot=heresNode;
                return;
            }
            //最后就是确认位置,让要删除节点的父节点认识新儿子
            if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
                parent.setLeftChild(heresNode);
            } else {
                parent.setRightChild(heresNode);
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值