数据结构之JAVA实现二叉搜索树

本文详细介绍了二叉搜索树的概念,包括其性质、查找、插入和删除操作的代码实现,以及性能分析,特别强调了在不同情况下的查找效率差异。
摘要由CSDN通过智能技术生成

二叉搜索树

什么是搜索树

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

1)若它的左子树不为空,则左子树上所有节点的值都小于根节点的值;

2)若它的右子树不为空,则右子树上所有节点的值都大于根节点的值;

3)它的左右子树也分别为二叉搜索树;

int array[ ]={ 5,3,4,1,7,8,2,6,0,9 };

1.查找

代码实现:

public TreeNode search(int key) {
        TreeNode cur=root;
        while(cur!=null){
            if(cur.key>key){
                cur=cur.left;
            }else if(cur.key<key){
                cur=cur.right;
            }else{
                return cur;
            }
        }
        return null;
    }

2.插入

1. 如果树为空树,即根 == null,直接插入;

2. 如果树不是空树,按照查找逻辑确定插入位置,插入新结点;

 public void insert(int key) {
        TreeNode newnode=new TreeNode(key);
        if(root==null) {
            root=newnode;
            return;
        }
        TreeNode parent=null;
        TreeNode cur=root;
        while(cur!=null) {
            if (cur.key > key) {
                parent = cur;
                cur = cur.left;
            } else if (cur.key < key) {
                parent = cur;
                cur = cur.right;
            } else {
                return;//不能插入相等的元素
            }
        }

            if(parent.key>key){
                parent.left=newnode;
            }else{
                parent.right=newnode;
            }

    }

3.删除

设待删除结点为 cur, 待删除结点的双亲结点为 parent;

1. cur.left == null

      1. cur 是 root,则 root = cur.right

      2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.right

      3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.right

2. cur.right == null

     1. cur 是 root,则 root = cur.left   

     2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.left

     3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.left

3. cur.left != null && cur.right != null

     需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被 删除节点中,再来处理该结点的删除问题;

代码:

//删除key的值
    public void remove(int key) {
        TreeNode parent=null;
        TreeNode cur=root;
        while(cur!=null){
            if (cur.key > key) {
                parent = cur;
                cur = cur.left;
            } else if (cur.key < key) {
                parent = cur;
                cur = cur.right;
            } else {
                removenode(parent,cur);
                return;
            }
        }
    }
    //封装函数
    public void removenode(TreeNode parent,TreeNode cur){
        if(cur.left==null){
            if(cur==root){
                root=cur.right;
            }else if(cur==parent.right){
                parent.right=cur.right;
            }else if(cur==parent.left){
                parent.left=cur.right;
            }
        }else if(cur.right==null){
            if(cur==root){
                root=cur.left;
            }else if(cur==parent.left){
                parent.left=cur.left;
            }else if(cur==parent.right){
                parent.right=cur.left;
            }
        }else{
            //用左数最小值替换cur,然后删除target
            TreeNode target=cur.right;
            TreeNode targetP=cur;
            while(target.left!=null){
                targetP=target;
                target=target.left;
            }
            cur.key=target.key;
            if(target==targetP.left){
                targetP.left=target.right;
            }else{
                targetP.right=target.right;
            }
        }
    }

总体代码展示:

public class BinarySearchTree {

    static class TreeNode {
        public int key;
        public TreeNode left;
        public TreeNode right;

        TreeNode(int key) {
            this.key = key;
        }
    }

    public TreeNode root=null;

    //查找key是否存在
    public TreeNode search(int key) {
        TreeNode cur=root;
        while(cur!=null){
            if(cur.key>key){
                cur=cur.left;
            }else if(cur.key<key){
                cur=cur.right;
            }else{
                return cur;
            }
        }
        return null;
    }

    /**
     * 插入一个元素
     *
     * @param key
     */
    public void insert(int key) {
        TreeNode newnode=new TreeNode(key);
        if(root==null) {
            root=newnode;
            return;
        }
        TreeNode parent=null;
        TreeNode cur=root;
        while(cur!=null) {
            if (cur.key > key) {
                parent = cur;
                cur = cur.left;
            } else if (cur.key < key) {
                parent = cur;
                cur = cur.right;
            } else {
                return;//不能插入相等的元素
            }
        }

            if(parent.key>key){
                parent.left=newnode;
            }else{
                parent.right=newnode;
            }

    }


    //删除key的值
    public void remove(int key) {
        TreeNode parent=null;
        TreeNode cur=root;
        while(cur!=null){
            if (cur.key > key) {
                parent = cur;
                cur = cur.left;
            } else if (cur.key < key) {
                parent = cur;
                cur = cur.right;
            } else {
                removenode(parent,cur);
                return;
            }
        }
    }
    //封装函数
    public void removenode(TreeNode parent,TreeNode cur){
        if(cur.left==null){
            if(cur==root){
                root=cur.right;
            }else if(cur==parent.right){
                parent.right=cur.right;
            }else if(cur==parent.left){
                parent.left=cur.right;
            }
        }else if(cur.right==null){
            if(cur==root){
                root=cur.left;
            }else if(cur==parent.left){
                parent.left=cur.left;
            }else if(cur==parent.right){
                parent.right=cur.left;
            }
        }else{
            //用左数最小值替换cur,然后删除target
            TreeNode target=cur.right;
            TreeNode targetP=cur;
            while(target.left!=null){
                targetP=target;
                target=target.left;
            }
            cur.key=target.key;
            if(target==targetP.left){
                targetP.left=target.right;
            }else{
                targetP.right=target.right;
            }
        }
    }
}

测试代码:

public class Test {
    public static void main(String[] args) {
        BinarySearchTree bt=new BinarySearchTree();
        bt.insert(10);
        bt.insert(5);
        bt.insert(19);
        bt.insert(6);
       // System.out.println(bt.search(5).key);
        bt.remove(10);
    }
}

性能分析:

      插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。

      对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度 的函数,即结点越深,则比较次数越多。

最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:log2N

最差情况下,二叉搜索树退化为单支树,其平均比较次数为:N/2

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卓娃也不e

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值