首页 > 编程语言 >数据结构-二叉搜索树(Java实现)

数据结构-二叉搜索树(Java实现)

时间:2024-03-27 12:01:12浏览次数:20  
标签:right Java cur parent null 二叉 val 数据结构 left

1. 概念

二叉搜索树也叫做二叉排序树,如果中序遍历,这棵二叉搜索树的结果就是有序的,它是具备以下性质的二叉树:

  • 若它的左子树不为空,则左子树上所有结点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上所有结点的值都大于根节点的值
  • 它的左右子树也分别为二叉搜索树

{5,3,4,1,7,8,2,6,0,9};
 

二叉搜索树的结构代码

    static class TreeNode {  //内部类
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {  //构造方法
            this.val = val;
        }
    }

    public TreeNode root;

 2. 操作-查找

 

    //查找
    public boolean search(int val) {
        TreeNode cur = root;

        //创建一个cur在root位置,如果比cur大就走到右边,反之左边,直到cur等于空跳出循环

        while (cur != null) {
            if (cur.val < val) {
                //往右树查找
                cur = cur.right;
            } else if (cur.val > val) {
                //往左树查找
                cur = cur.left;
            } else {
                //找到了
                return true;
            }
        }
        //没有则返回false
        return false;
    }

    

(1) 如果树为空树,即根 == null,直接插入

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

    //插入
    //要记录上一个的结点
    public void insert(int val) {
        if (root == null) {  //第一个结点的处理
            root = new TreeNode(val);
            return;
        }
        TreeNode cur = root;
        TreeNode parent = null;

        while (cur != null) {  //cur走到空的地方,证明走到了,然后通过cur的父节点parent来判断插入左边还是右边
            if (cur.val < val) {
                parent = cur;  //先走到cur位置,cur再动
                cur = cur.right;
            } else if (cur.val > val) {
                parent = cur;
                cur = cur.left;
            } else {
                return;
            }
        }
        //new一个要插入的结点,把val放进去构造好
        TreeNode node = new TreeNode(val);
        //插入必须是叶子结点,所以cur到达null
        if (parent.val < val) {
            parent.right = node;
        } else {
            parent.left = node;
        }
    }

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 = 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   (难点)

需要使用替换法进行删除,即寻找所要删除结点的左子树的最大值或者右子树的最小值,对所要删除结点进行覆盖,这样就能达到删除效果

 

    //删除操作
    public void remove(int val) {
        TreeNode cur = root;  //从根节点开始找
        TreeNode parent = null;
        while(cur != null) {
            if(cur.val < val) {  //说明要删除的结点在cur的右边
                parent = cur;  //parent走到cur当前位置
                cur = cur.right;  //cur往右边走
            }else if(cur.val > val) {  说明要删除的结点在cur的左边
                parent = cur;  //parent走到cur当前位置
                cur = cur.left;  //cur往左边走
            }else {  //找到要删除的结点
                removeNode(parent,cur);
                return;
            }
        }
    }
    private void removeNode(TreeNode parent,TreeNode cur){
        if(cur.left == null) {  //左边等于空
            if (cur == null) {
                root = cur.right;
            } else if (cur == parent.left) {
                parent.left = cur.right;
            } else {
                parent.right = cur.right;
            }
        } else if (cur.right == null) {  //右边等于空
            if(cur == null) {
                root = cur.left;
            } else if (cur == parent.left) {
                parent.left = cur.left;
            }else {
                parent.right = cur.left;
            }
        }else { //左右都不为空
            TreeNode t = cur.right;  //寻找所要删除结点右子树的最小值
            TreeNode tp = cur;
            while(t.left != null) {  //等于null说明找到最小值了
                tp = t;  //父亲结点先走到cur位置
                t = t.left;  //往左边寻找最小值
            }
            cur.val = t.val;  //进行替换
            if (tp.left == t.left) {  //删除结点,两种情况
                tp.left = t.right;
            } else {
                tp.right = t.right;
            }
        }
    }
}

 

 

 

标签:right,Java,cur,parent,null,二叉,val,数据结构,left
From: https://blog.csdn.net/cj13106811623/article/details/137012729

相关文章

  • 数据结构-排序算法(Java实现)
    1.插入排序1.1基本思想把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。1.2图解 1.3原理解析第一趟:一组数据可以分为有序序列和无序序列, i表示无序序列的第一个元素,j表示有序序列的......
  • Java8递归生成树
    @Data@BuilderpublicclassMenu{/***id*/publicIntegerid;/***名称*/publicStringname;/***父id,根节点为0*/publicIntegerparentId;/***子节点信息*/publicList<Menu>......
  • Java集合排序
    packagecom.example.demo;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;importjava.util.List;publicclassTestApp{/**Comparable是一个内部比较接口,通常对象需要内部排序时直接实现Comparator是一个外......
  • java毕业设计基于微信小程序的图书馆预约[附源码]
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着移动互联网技术的飞速发展,微信小程序凭借其无需下载安装、使用方便的特点,已经成为人们日常生活中不可或缺的一部分。图书馆作为知识传播的重要场所,在......
  • Java语言程序设计2
    第二章、变量、数据变量、运算符、表达式一、变量1.概念:计算机中的一块内存空间,存储数据的基本单元2.变量的组成部分:数据类型,变量名,数据3.语法:(1)先声明,在赋值:    数据类型变量名;//声明    变量名=值;//值(2)声明同时并赋值:    数据类型变量......
  • java的封装
    封装概述    java中的封装指的是将一系列有关的事物的共同属性和行为提取出来放到一个类中,隐藏对象的实行和现实细节,仅对外提供公共的访问方式的操作。这样说起来感觉很抽象,也不好理解,这里不妨举一个例子。将配置电脑这个动作看成封装。    这个要怎么理解呢......
  • Java进阶 - [1-4] 反射
      一、类加载区别当我们刚接触java语言的时候,我们最常见的代码应该就是初始化某个对象,然后调用该对象的方法。1、使用new创建对象,返回对象的引用。Studentstudent=newStudent();2、调用方法:student.say(); 当我们想在运行期才能指定具体对象的类型或调用的某个方法......
  • 浏览器工作原理与实践--渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的
    在上篇文章中,我们介绍了渲染流水线中的DOM生成、样式计算和布局三个阶段,那今天我们接着讲解渲染流水线后面的阶段。这里还是先简单回顾下上节前三个阶段的主要内容:在HTML页面内容被提交给渲染引擎之后,渲染引擎首先将HTML解析为浏览器可以理解的DOM;然后根据CSS样式表,计算出DOM......
  • 浏览器工作原理与实践--渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的
    在上一篇文章中我们介绍了导航相关的流程,那导航被提交后又会怎么样呢?就进入了渲染阶段。这个阶段很重要,了解其相关流程能让你“看透”页面是如何工作的,有了这些知识,你可以解决一系列相关的问题,比如能熟练使用开发者工具,因为能够理解开发者工具里面大部分项目的含义,能优化页面卡......
  • Java使用AES加密
    publicclassAESUtil{publicstaticfinalStringalgorithm="AES";//AES/CBC/NOPaddin//AES默认模式//使用CBC模式,在初始化Cipher对象时,需要增加参数,初始化向量IV:IvParameterSpeciv=new//IvParameterSpec(key.getBytes());/......