【JAVA】二叉搜索树的一些功能实现(递归)

目录

1.概念

2.功能

2.1查找元素

2.1.1查找最大值

2.1.2查找最小值

2.2添加元素

2.3删除元素

2.3.1删除最大值

2.3.2删除最小值

2.3.3删除任意节点


1.概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 :
  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

例如:

2.功能

先建立一棵树。

    public class MyBST {
        //先实现一棵树
        private TreeNode root;
        private int size;
        private static class TreeNode{
            int val;
            TreeNode left;
            TreeNode right;

            public TreeNode(int val) {
                this.val = val;
            }
        }
    }

2.1查找元素

2.1.1查找最大值

二叉搜索树的最大值一定在最右边。

        //查找最大值
        public int max(){
            if(size==0){
                throw new NoSuchElementException("tree is empty");
            }
            TreeNode maxNode=findMaxNode(root);
            return maxNode.val;
        }

        private TreeNode findMaxNode(TreeNode root) {
            if(root.right==null){
                return root;
            }
            return findMaxNode(root.right);
        }

2.1.2查找最小值

二叉搜索树的最小值一定在最左边。

        //查找最小值
        public int min() {
            if (size == 0) {
                throw new NoSuchElementException("tree is empty");
            }
            TreeNode minNode=findMinNode(root);
            return minNode.val;
        }

        private TreeNode findMinNode(TreeNode root) {
            if(root.left==null){
                return root;
            }
            return findMinNode(root.left);
        }

2.2添加元素

根据节点值元素的大小,判断在哪里添加元素。

        //添加元素
        public void add(int val){
            root=add(root,val);
        }
        private TreeNode add(TreeNode root,int val){
            if(root==null){
                TreeNode node=new TreeNode(val);
                size++;
                return node;
            }else if(root.val<val){
                root.right=add(root.right,val);
                return root;
            }
            root.left=add(root.left,val);
            return root;
        }

2.3删除元素

2.3.1删除最大值

先找到最大值所在的节点(即最右边的节点)

如果最大值有左孩子,则删除最大值后左孩子就变为新的最大值。返回新节点。

如果没有左孩子,则直接返回删除后的新节点。

    //删除最大值
    public int removeMax(){
        //先找到最大值所在的节点
        TreeNode maxNode=findMaxNode(root);
        //将root更新为删除后的root
        root=removeMax(root);
        return maxNode.val;
        }
        //在以root为根节点的BST中,删除最大值的节点,返回删除后的根节点
        private TreeNode removeMax(TreeNode root){
            if(size==0){
                throw new NoSuchElementException("tree is empty");
            }
            if(root.right==null){
                //此时root就是最大值节点
                TreeNode left=root.left;
                //将右孩子放到根节点上,同时将根节点变为叶子节点
                root.left=root=null;
                size--;
                return left;
            }
            //此时继续在右子树中删除节点
            root.right=removeMax(root.right);
            return root;
        }

2.3.2删除最小值

先找到最小值所在的节点(即最左边的节点)

如果最小值有右孩子,则删除最小值后右孩子就变为新的最大值。返回新节点。

如果没有右孩子,则直接返回删除后的新节点。

    //删除最小值
    public int removeMin(){
            TreeNode minNode=findMinNode(root);
            root=removeMin(root);
            return minNode.val;
    }
    private TreeNode removeMin(TreeNode root){
            if(root.left==null){
                TreeNode right=root.right;
                root.right=root=null;
                size--;
                return right;
            }
            root.left=removeMin(root.left);
            return root;
    }

2.3.3删除任意节点

先找到值为val的节点。有三种情况:

1.此节点为最大值节点,使用removeMax()方法

2.此节点为最小值节点,使用removeMin()方法

3.此节点为除最大最小值节点的其它节点

当为第三种情况时。
例如下图:要删除值为15的节点。需要移动一个节点到被删除节点的位置上来。

 

此节点需要满足:

以此节点为根的左子树上的值都小于根节点的值,右子树上的值都大于根节点的值。

那么纵观全图,有两个节点合适。即14和18。

 这里我们以右子树上的18来写代码。

    //删除值为val的节点
    public void remove(int val){
            remove(root,val);
    }
    //在以root为根的BST中删除值为val的节点,返回删除后的树根节点
    private TreeNode remove(TreeNode root,int val){
            //先找到值为val的节点在哪里
        if(root==null){
            //递归到叶子节点,还是没有找到值为val的节点
            return null;
        }else if(val<root.val){
            root.left=remove(root.left,val);
            return root;
        }else if(val>root.val){
            root.right=remove(root.right,val);
            return root;
        }else{
            //找到了值val所在的节点
            //此节点为最大值节点时
            if(root.right==null){
                TreeNode left=root.left;
                root.left=root=null;
                size--;
                return left;
                //此节点为最小值节点时
            }else if(root.left==null){
                TreeNode right=root.right;
                root.right=root=null;
                size--;
                return right;
            }
            //此时左右子树都不为空
            //右子树最小值
            TreeNode successor=findMinNode(root.right);
            successor.right=removeMin(root.right);
            successor.left=root.left;
            root.left=root.right=root=null;
            return successor;
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值