数据结构与算法---二叉搜索树java实现

一、 二叉搜索树简介

二叉搜索树是一棵左子树节点永远小于根节点,右子树永远大于根节点的二叉树

二、实现细节

1. 增加元素
  1. 每次增加都在叶子结点,当要增加的元素等于根节点的值的时候不做操作直接将该数返回。
  2. 当要增加的元素小于根节点的时候,在左子树加入该节点,并把左子树更新为增加节点后的左子树。
  3. 当大于根节点的时候,在子右树加入该节点,并把右子树更新为增加节点后的右子树子树。
2. 删除元素
  • 当要删除的元素小于根节点的时候,在左子树删除该节点,并把左子树更新为删除节点后的左子树。

  • 当要删除的元素大于根节点的时候,在右子树删除该节点,并把右子树更新为删除节点后的右子树。

  • 当要删除的元素为根节点的时候,此时分为三种情况:
    1. 左右子树都为空直接删除节点。
    2. 只有一个子树,删除当前节点,将父节点指向该节点的指针指向该节点的唯一孩子节点。
    3. 当该节点有两个孩子的时候,采取的办法就是找到大小离他最近的元素(左子树的最大值/右子树的最小值),将当前节点的值重置为离他最近的元素(左子树的最大值/右子树的最小值),将离他最近的元素所在的节点删除。

代码

public class BinarySearchTree <T extends Comparable> {

    private BinaryNode <T>root;

    public BinarySearchTree() {

    }
    public BinarySearchTree(T element) {
        this.root = new BinaryNode<T>(element,null,null);
    }
    /**
     * 在当前树上插入元素
     * */
    public void insert(T element){
        root = insert(element,root);
    }
    /**
     * 在树上插入元素并返回新树
     * */
    private BinaryNode<T> insert(T element,BinaryNode root){
        if (root == null) //如过是空的时候直接新建节点返回-----即把新建的节点返回赋值给父节点的某个子树
             return new BinaryNode<T>(element,null,null);

        int flag = element.compareTo(root.element);

        if (flag<0) //要插入的元素比当前元素小插入到左子树
            root.left = insert(element,root.left);
        else if (flag>0) //要插入的元素比当前元素大插入到右子树中
            root.right = insert(element,root.right);
        else //要插入的元素等于当前元素什么也不做---为了便于理解写出来
            ;
        return root; //最后将插入好的树返回
    }

    public boolean contain(T element){
        return contain(element, root);
    }
    /**
     * 判断元素是否包含在树中
     * */
    private boolean contain(T element,BinaryNode root){
        if(root==null)
            return false;
        boolean is;
        int flag = element.compareTo(root.element);
        if (flag<0)
            is =contain(element,root.left); //没有找到在当前左子树上寻找
        else if (flag>0)
            is = contain(element,root.right); //没有找到在当前右子树上寻找
        else
            return true;
        return is;
    }


    /**
     * 删除元素
     * */
    public void remove(T element){
        root = remove(element,root);
    }

    public BinaryNode<T> remove(T element,BinaryNode<T> root){
        if (root!=null){
            int flag = element.compareTo(root.element);
            if(flag<0){
                root.left = remove(element,root.left);
            }
            else if (flag>0){
                root.right  = remove(element,root.right);
            }
            else{
                //当前的节点就是要删除的节点
                //1. 没有孩子
                if (root.left==null&&root.right==null){
                    return null;
                }
                //2. 有一个孩子
                else if(root.left==null||root.right==null){
                    return root.left==null?root.right:root.left;//返回不为空的那个孩子
                }
                //3. 有两个孩子
                else{
                    //将当前节点的值设置为距离他最近的节点的元素(遍历后在他后边),
                    //对应着右子树的最小值,左子树的最大值
                    //现在选择右子树的最小值
                    root.element = removeMin(root.right);
                }
            }
        }
        return root;
    }
    //将最小值删除并返回他的值
    private T  removeMin(BinaryNode<T> root){
        BinaryNode <T> node = root;
        BinaryNode <T> parent = root;
       while(node.left!=null){
           parent = node;
           node = node.left;
       }
        parent.left = node.right;
        return node.element;
    }

    private static class BinaryNode<T>{
        T element;
        BinaryNode<T> left;
        BinaryNode<T> right;
        public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {
            this.element = element;
            this.left = left;
            this.right = right;
        }
    }

    public static void main(String[] args) {
        BinarySearchTree<Integer> tree = new BinarySearchTree<>();
        tree.insert(5);
        tree.insert(3);
        tree.insert(6);
        tree.insert(4);
        tree.insert(4);

        boolean is = tree.contain(7);
        tree.remove(3);

        System.out.println(is);
        System.out.println();
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值