二叉搜索树(数据结构)

1二叉搜索树的定义:树中不能有相同的数据

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

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

他的右左子树也是二叉搜索树

上代码:


    static class Node
    {   int data;
        public Node(int data)
       {
           this.data=data;
       }
        Node left;
        Node right;
    }
   static class Searchtree {
        Node root=null;
        public Node search(int data)
        {  if(root==null)
           {
          return null;
           }
         Node current=root;
          while(current!=null)
          {
              if(current.data==data)
              {
                  return current;
              }else if(current.data>data)
              {
                  current=current.left;
              }else
              {
                  current=current.right;
              }

          }
          return null;
      }
      public boolean put(int data)//二叉搜索树的插入,每次一定都插到了叶子节点处的位置,注意一种情况
      {    Node node=new Node(data);           //如果原来的二叉搜索树里面有data数据,那一定就插入失败啦.况且还要定义一个节点,定义上一个节点
          if(root==null)
          {   root=node;
             // root.data=data;
              return true;
          }
          Node front=null;
          Node current=root;
          while(current!=null){
              if(current.data==data)
              {
                  return false;//二叉搜索树的数据是不可以和data值相同
              }else if(current.data > data){
                  front=current;
                  current=current.left;
          }else{
                  front=current;
                  current=current.right;
              }

              }
          if(front.data>data) {//此时的front一定是叶子结点
              front.left=node;
          }
          else {
              front.right=node;
      }
          return true;
      }
      public void show()//二叉树的层序遍历
      {
          Queue <Node> queue=new LinkedList();
            if(root==null) return;
            Node current=root;
            queue.offer(root);
            while(!queue.isEmpty())
            {
                Node top=queue.poll();
                System.out.println(top.data);
                if(top.left!=null)
                {
                    queue.offer(top.left);
                }
                if(top.right!=null)
                {
                    queue.offer(top.right);
                }

            }

      }

下面我们来介绍一下,二叉搜索树的删除(难点)

先找到对应删除的节点

删除操作真的非常复杂(先查找要删除的节点,查找到后,还要知道双亲结点)

cur表示要删除的节点

1 cur.left==null

(1) cur==root;

(2) cur=parent.left;

(3) cur=parent.right;

2 cur.right==null

(1) cur==root;

(2) cur=parent.left;

(3) cur=parent.right;

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

1)重点:就要用到替罪羊方法(找右树最左面的节点)(也可以找左树最右面的节点)然后互换;

这个法则又分为进入循环和没有进行到循环

2)注意当我们找右树最左边的节点的时候Node,虽然他是右树最左边的结点,但是他的右树可能还是有数据的

parent=current;

child=current.left;

//不可以这么写

parent=current.right;

child=parent.left;

删除的代码如下:

 public void delete(Node current,Node parent)
        {
            if(current.left==null)
            {
                if(current==root)
                {
                    root=root.right;
                    return;
                }
                else if(current==parent.left)
                {
                    parent.left=current.right;
                    return;
                }
                else{
                    parent.right=current.right;
                    return;
                }
            }
            else if(current.right==null)
            {
                if(current==root)
                {
                    root=root.left;
                    return;
                }else if(current==parent.left)
                {
                    parent.left=current.left;
                    return;
                }
                else
                {
                    parent.right=current.left;
                    return;
                }
            }
            else
            {
                Node parent1=current;
                Node current1=current.right;
                while(current1.left!=null)
                {

                    current=current.left;
                    parent1=current1;
                }
                current.data=current1.data;
                if(parent1.right==current1)
                {
                    parent1.right=current1.right;
                    return;
                }
                else
                {
                    parent1.left=current1.right;
                    return;
                }
            }
        }
        public void removeall(int data)
        {   if(root==null) return;
            Node current=root;
            Node parent=null;
            while(current!=null)
            {
                if(current.data==data)
                {
                    delete(current,parent);
                    return;
                }
                else if(current.data<data)
                {   parent=current;
                    current=current.right;
                }else
                {
                    parent=current;
                    current=current.left;
                }
            }
        }
        public void show()
        {
            Queue <Node> queue=new LinkedList();
            if(root==null) return;
            Node current=root;
            queue.offer(root);
            while(!queue.isEmpty())
            {
                Node top=queue.poll();
                System.out.print(" "+top.data);
                if(top.left!=null)
                {
                    queue.offer(top.left);
                }
                if(top.right!=null)
                {
                    queue.offer(top.right);
                }

            }

        }

    }

变成完全二叉树的情况最好logN,不好的情况下会变成单分支的树,高度变成但分值的树

但是AVL树要不断进行旋转

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
二叉搜索树(Binary Search Tree)是一种具有特定性质的二叉树。它可以是一棵空树,或者满足以下条件: 1. 如果左子树不为空,则左子树上所有节点的值都小于根节点的值。 2. 如果右子树不为空,则右子树上所有节点的值都大于根节点的值。 3. 左右子树也分别为二叉搜索树二叉搜索树作为一种经典的数据结构,具有许多优点。它既支持链表的快速插入和删除操作,又支持组的快速查找操作。因此,在文件系统和据库系统等领域,经常使用二叉搜索树来实现高效的排序和检索操作。 二叉搜索树的主要操作包括插入、遍历、查找和删除。插入操作将一个新节点插入到合适的位置,遍历操作按照规定的顺序访问树的各个节点,查找操作根据给定的值在树找到对应的节点,删除操作将指定节点从树删除。 关于二叉搜索树的性能分析,它的查找和插入操作的平均时间复杂度为O(logN),其N是树节点的量。但是,如果树变得不平衡,最坏情况下的时间复杂度可能达到O(N)。为了避免树的不平衡,可以使用平衡二叉搜索树如AVL树进行优化。 总结来说,二叉搜索树是一种常用的数据结构,它具有快速插入和删除的特点,同时也支持高效的查找操作。但需要注意,为了保持性能,需要保持树的平衡。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【数据结构二叉搜索树剖析(附源码)](https://blog.csdn.net/weixin_52344401/article/details/122908681)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【Java 数据结构】实现一个二叉搜索树](https://blog.csdn.net/m0_61784621/article/details/128405350)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值