二叉搜索树(数据结构)

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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值