数据结构—二叉搜索树

本文介绍了数据结构中的二叉搜索树,包括其定义、性质。内容涵盖二叉树的概念,二叉搜索树的特点,如左子树小于根节点、右子树大于根节点。讨论了二叉搜索树的插入、删除操作,以及前驱结点和后继结点的概念。还提到了树的遍历方式,包括前序、中序、后序和层序遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#数据结构—二叉搜索树

1.什么是树:

一种非线性的数据结构

一个结点只有一个父节点,零个或多个子节点;除了父节点以外每个结点只有一个父节点,并且兄弟结点不相:

结点的度:每个结点所拥有子树的数目;

兄弟结点:有相同父节点的结点;

树的度:最大度结点,的度叫做树的度;

树的深度:根到叶子节点的所连的边的数目,

数的高度:树的深度反过来;

树的层数:树的深度+1;

2.二叉树:

除了叶子节点以外,每个结点最多有两个子树;

二叉搜索树: 每个结点的左子树都比该节点小,每个结点的右子树都比该节点大;

首先二叉搜索树的结点插入:

思路:以当前节点为根节点为节点;

    public void add(E e) {
        root=add(root,e);
    }
    private Node add(Node root,E e){
        if(root==null){
            size++;
            return new Node(e);
        }
        if((e.compareTo(root.e))<0){
            root.left=add(root.left,e);
        }
        if((e.compareTo(root.e))>0){
            root.right=add(root.right,e);
        }
        return root;
    }

查找当前数是否有指定的结点

 public boolean contains(E e) {

        return contains(root,e);
    }
    private boolean contains(Node root,E e){
        if(root==null){
            return false;
        }
        if(root.e.equals(e)){
            return true;
        }else if((e.compareTo(root.e))<0){
            return contains(root.left,e);
        }else {
            return contains(root.right,e);
        }
    }

找到最小的结点

 public E removeMin() {
        if (root==null)
        return null;
        root=removeMin(root);
        return root.e;
    }
    private Node removeMin(Node root){
        if(root.left==null){
            if (root.right!=null){
                Node temp=root.right;
                root.right=null;
                size--;
                return temp;

            }
        }
        root.right=removeMax(root.right);
        return root;

    }
  public E removeMax() {
        if(root==null){
            return null;
        }
        root=removeMax(root);
        return root.e;
    }
    private Node removeMax(Node root){
        if(root.right==null){
            if (root.left!=null){
                Node temp=root.left;
                root.left=null;
                size--;
                return temp;

            }
        }
        root.left=removeMax(root.left);
        return root;
    }

删除最小结点

public E removeMin() {
    if(root==null){
        return null;
    }
    return removeMin(root.left).e;
}
//返回最小结点
private Node removeMin(Node root){
    //如果当前节点的左子树为空,说明找到了要删除的结点;
    if(root.left==null){
        //保存当前节点的右子树
        Node temp=root.right;
        //将当前节点的右数置为空
        root.right=null;
        size--;
        //返回当前节点
        return temp;
    }
    //将返回的结点连在子树上
    root.left=removeMin(root.left);
    //返回结点
    return  root;
}

删除最大结点 和删除最小节点的逻辑一样

public E removeMax() {
    if(root==null){
        return null;
    }
    return removeMax(root).e;
}
private Node removeMax(Node root){
     //如果当前节点的右子树为空,说明找到了要删除的结点;
    if(root.right==null){
         //保存当前节点的左子树
        Node temp=root.right;
         //将当前节点的左子树为空
        root.right=null;
        size--;
        return temp;
    }
    //连上最新的子树;
    root.right=removeMax(root.right);
    return root;
}

删除指定结点:

  public void remove(E e) {

        root=remove(root,e);
    }
 private Node remove(Node root,E e){
        if (root==null){
            return null;
        }
        if(root.e.equals(e)){
            if(root.left==null){
                Node right=root.right;
                root.right=null;
                size--;
                return right;
            }
            if(root.right==null){
                Node left=root.left;
                root.left=null;
                size--;
                return left;
            }
            if(root.left!=null&&root.right!=null){
                Node s=findMin(root.right);
                s.right=removeMin(root.right);
                s.left=root.left;
                size--;
                return s;
            }
        }else if((e.compareTo(root.e))<0){
            root=remove(root.left,e);
            return root;
        }else {
            root=remove(root.right,e);
            return root;
        }
        return root;
    }

前驱结点,比当前结点小的子树的最大结点;

后继结点,比当前节点大的子树的最大结点;

树的前序遍历

  public void preOrder() {
        preOrder(root);
    }
    private void preOrder(Node root){
        if(root==null){
            return;
        }
        //第一次访问根节点就输出根节点先输出根节点
        System.out.println(root.e);
        //向左树递归
        preOrder(root.left);
        //向右树递归
        preOrder(root.right);

    }

中序遍历

 public void inOrder() {
        inOrder(root);
    }
    private void inOrder(Node root){
        if(root==null){
            return ;
        }
        inOrder(root.left);
        //第二次访问根节点的时候输出
        System.out.println(root.e);
        inOrder(root.right);
    }

后序遍历

@Override
public void postOrder() {
    postOrder(root);
}
private void postOrder(Node root){
    if(root==null){
        return;
    }
    postOrder(root.left);
    postOrder(root.right);
    //第三次访问结点的时候输出
    System.out.println(root.e);
}

层序遍历:所有广度优先遍历使用队列来进行迭代输出

public void levelOrder() {
    if(root==null){
        return;
    }
    //将当前节点入队
    LinkedList<Node> queue=new LinkedList<>();
    queue.add(root);
    //当结点不为空,说明不断有结点入队
    while(!queue.isEmpty()){
        //将队头结点出队
        Node temp=queue.poll();
        //输出当前节点
        System.out.println(temp.e);
        //如果左子树不为空,入队
        if(temp.left!=null){
            queue.add(root.left);
        }
        //如果右子树不为空,入队
        if(temp.right!=null){
            queue.add(root.right);
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值