java二叉搜索树详解

article/2025/8/25 1:13:35

文章目录

  • 一、概念
  • 二、相关操作
    • 2.0节点相关代码:
    • 2.1查找
    • 2.2插入
    • 2.3删除(重难点)
    • 2.4测试用例
  • 三、小结


提示:以下是本篇文章正文内容,下面案例可供参考

一、概念

二叉搜索树又称二叉排序树
它或者是一棵空树,或者是具有以下性质的二叉树:
1.若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
2.若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
3.它的左右子树也分别为二叉搜索树
ps:二叉搜索树的中序遍历一定是有序的(从小到大)
在这里插入图片描述
(图片来自比特就业课)

二、相关操作

2.0节点相关代码:

class Node{//和二叉树没有什么区别public int val;public Node left;public Node right;public Node(int val){this.val=val;}
}

2.1查找

在这里插入图片描述
(图片来自比特就业课)

代码如下(示例):

public Node search(int key){Node cur=root;while(cur!=null){if(cur.val<key){cur=cur.right;}else if(cur.val==key){return cur;}else{cur=cur.left;}}return null;//走到这里,说明上面while没找到,也就是没有这个数据}

2.2插入

二叉搜索树的插入分两种情况:
1.树本身就空的,你直接插入即可

2.树不是空树,但由于二叉搜索树的有序性质,如下图,我们要插入1给元素10的节点,10比5大,往右走;10比7大,往右走;10比8大,往右走;10比9大,往右走;发现9右边没有节点了,10就放在9节点的右边。

ps:对于二叉搜索树这种特殊的树,插入的节点一定会在叶子节点
在这里插入图片描述
(图片来自比特就业课)
代码如下(示例):

public boolean insert(int val){if(root==null){root=new Node(val);return true;}Node newNode=new Node(val);//要插入的节点Node cur=root;//用来遍历的节点Node parent=null;//这个节点是用来标记cur的位置的(方便知道最后插入节点parent左边还是右边)//你可以理解为,parent就是上一个cur位置while(cur!=null){if(cur.val< val){parent=cur;cur=cur.right;}else if(cur.val> val){parent=cur;cur=cur.left;}else{//两个数据相同(搜索二叉树中不存在相同数据的情况)return false;}}if(parent.val<val){parent.right=newNode;}else if(parent.val>val){parent.left=newNode;}return true;}

2.3删除(重难点)

删除分3种大情况,大情况下又分3种小情况:
我们这里设待删除结点为 cur, 待删除结点的双亲结点为 parent
1.cur.left == null
①cur 是 root,则 root = cur.right
如下图:我现在要删除5这个节点,5节点左边没有节点,把12变成root即可在这里插入图片描述

②cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
如下图p是11,cur是10,现在删除cur,那么让p的左孩子变成8即可
在这里插入图片描述

③cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
如下图:要删除12,把要删除节点的父亲结点5与删除节点的右节点15连接
在这里插入图片描述

2.cur.right == null
①cur 是 root,则 root = cur.left
如下图,要删除19这个节点,19右边没有节点的,我们让12成为新的根即可
在这里插入图片描述

②cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
如下图:要删除12,把删除节点的双亲节点19与要删除节点的子节点8连接
在这里插入图片描述

③cur 不是 root,cur 是 parent.right,则 parent.right = cur.left
如下图:要删除30,把30的双亲节点19与30的左孩子节点连接
在这里插入图片描述

3.cur.left != null && cur.right != null
两种处理方法:
在被删除节点的左子树找最大值,放被删除位置
在被删除节点的右子树找最小值,放被删除位置
两种方法都是为了保证,删除掉某个节点后,该二叉树任然是二叉搜索树

如下图:我们现在要删70,怎么做?直接删吗?把90放在70的位置吗?假设把90放70的位置,那75是90的左节点啊,75怎么放呢?
在这里插入图片描述

这里先公布一下正确放法:

法一:把54放到70位置
在这里插入图片描述

法二:把75放到70的位置,如下图
在这里插入图片描述
上面两种方法都可以保证删除掉某个节点后仍然是搜索二叉树

我们以法二进行举例,如何在要删除节点的右子树找最小值
在这里插入图片描述
遍历找到最小值75后,把75放到要删除数据70的位置,90与83连接,然后90与75,75与83的连接断开。
ps:这里90与83相连是83放90左边,但如果83是90以上的数,比如100,就要放在90的右边了,连接的时候需要进行判断一下。
(另一种方法类推即可,这里不过多赘述)
代码如下(示例):

public void remove(int key){Node cur=root;Node parent=null;while(cur!=null){if(cur.val==key){//找到要删除的数了removeNode(cur,parent);//进行删除操作break;}else if(cur.val<key){parent=cur;cur=cur.right;}else{parent=cur;cur=cur.left;}}}public void removeNode(Node cur,Node parent){if(cur.left==null){//cur没有左孩子节点if(cur==root){root=cur.right;}else if(cur==parent.left){parent.left=cur.right;}else if(cur==parent.right){parent.right = cur.right;}}else if(cur.right==null){//cur没有右孩子节点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 if(cur.left!=null&&cur.right!=null){//在要删除节点的右子树找最小值//我们这里创建变量,target表示要找的最小值节点Node targetParent=cur;//记录target的上一个位置Node target=cur.right;while(target.left!=null){//只往左边找(二叉搜索树左值<根<右值)targetParent=target;target=target.left;}cur.val=target.val;//target值放到要删除节点去if(target==targetParent.left){//target节点在它双亲节点左边,比如文章图中75在90左边targetParent.left=target.right;}else if(target==targetParent.right){targetParent.right = target.right;}}}

2.4测试用例

//用中序遍历(左根右),如果是二叉搜索树,则中序遍历一定是有序的public void inOrder(Node root){if(root==null){return;}inOrder(root.left);System.out.print(root.val+" ");inOrder(root.right);}public static void main(String[] args) {int []arr={10,8,19,3,9,4,7};BinarySearchTree binarySearchTree=new BinarySearchTree();//测试插入数据for(int i=0;i<arr.length;i++){binarySearchTree.insert(arr[i]);}binarySearchTree.inOrder(binarySearchTree.root);//打印3 4 7 8 9 10 19System.out.println();//测试插入重复数据boolean b=binarySearchTree.insert(7);System.out.println(b);//打印false//测试删除数据binarySearchTree.remove(8);binarySearchTree.inOrder(binarySearchTree.root);//打印3 4 7 9 10 19 (仍然有序,且没有8这个值)}

在这里插入图片描述

三、小结

二叉搜索树概念不难,简单来说就是左节点值<根值<右节点值。三个方法中
查找和插入并不难,但是删除讨论的情况较多,建议读者,一定要先看懂图!这样看代码才更加清晰。最后祝您生活愉快。


http://chatgpt.dhexx.cn/article/HV0dRFJU.shtml

相关文章

二叉搜索树

目录 二叉搜索树二叉搜索树概念 增删查改接口插入递归插入查找递归查找删除递归删除 成员函数拷贝构造拷贝赋值析构 二叉搜索树的应用二叉搜索树的性能分析 二叉搜索树 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的…

【数据结构】二叉搜索树

目录 一.二叉搜索树规则 二.框架 三.实现 1.查找, 插入, 删除 迭代法实现 递归法实现 2.构造, 赋值 默认构造 拷贝构造 赋值运算符重载 3.中序遍历 四.时间复杂度及稳定性 五.key模型与key/value模型 1.key模型 2.key/value模型 一.二叉搜索树规则 二叉搜索树又…

数据结构——二叉搜索树详解

二叉搜索树 一、什么是二叉搜索树 二叉搜索树&#xff08;BST&#xff0c;Binary Search Tree&#xff09;&#xff0c;也称二叉排序树或二叉查找树。 二叉搜索树&#xff1a;一棵二叉树&#xff0c;可以为空&#xff1b;如果不为空&#xff0c;满足以下性质&#xff1a; 非空…

【数据结构】——二叉搜索树

目录 前言 二叉搜索树的概念 二叉搜索树的操作 树的节点实现 搜索树的基本结构 插入数据 查找 删除 拷贝构造函数 二叉搜索树的应用 前言 在c中的容器里map和set的学习需要二叉搜索树的铺垫&#xff0c;也为后边的的红黑树和AVL树做铺垫&#xff0c;也就是说&#xff0c;…

二叉搜索树(二叉排序树)

一.概念 二叉搜索树又称二叉排序树&#xff0c;具有以下性质&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树 注意&#xff1a;二…

二叉排序树(二叉查找树、二叉搜索树)(图解+完整代码)

目录 ⚽1.什么是二叉排序树 &#x1f3d0;2.构建二叉排序树 &#x1f3c0;3.二叉排序树的查找操作 &#x1f94e;4.二叉排序树的删除 &#x1f3b1;5.完整代码 ⚽1.什么是二叉排序树 我们直接看它的性质&#xff1a; 若它的左子树不空&#xff0c;则左子树上所有结点的值…

种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林

虽然今天不是植树节&#xff0c;但是我今天想种树。 文章目录 树&#xff0c;什么是树&#xff1f;二叉树定义二叉树的创建二叉树的前中后序遍历前序遍历&#xff1a;中序遍历后序遍历已知前序、中序遍历结果&#xff0c;还原二叉树已知后序、中序遍历结果&#xff0c;还原二叉…

java lrucache_Java LruCache 的使用及原理

概述 LRU (Least Recently Used) 的意思就是近期最少使用算法&#xff0c;它的核心思想就是会优先淘汰那些近期最少使用的缓存对象。 在我们日常开发中&#xff0c;UI 界面进行网络图片加载是很正常的一件事情&#xff0c;但是当界面上的图片过于多的时候&#xff0c;不可能每次…

LruCache和DiskLruCache

前言 Android中的三级缓存主要就是内存缓存和硬盘缓存。 Lru(least recently used)意为最近最少使用算法&#xff0c;核心思想就是当缓存满时&#xff0c;会优先淘汰最近最少使用的缓存对象。 LruCache的使用 在Android中可以直接使用LruCache&#xff0c;算法原理是&#xff1…

Android LruCache 缓存

使用场景 1、场景一&#xff1a;图片缓存利器。 可以规定缓存大小、有效避免OOM、自动移除队尾不用的图片缓存、避免HashMap各种问题。 2、场景二&#xff1a;通信缓存 从服务端需要获取数据&#xff0c;但是当访问的数据比较大&#xff0c;比较多&#xff0c;并且是重复数…

Java——LRUCache

概念 简单来说&#xff0c;由于我们的空间是有限的&#xff0c;所以发明了这个数据结构&#xff0c;当我们的空间不够添加新的元素时&#xff0c;就会删除最近最少使用的元素。 其底层逻辑通过哈希表和链表共同实现。哈希表中存储链表的每一个元素&#xff0c;方便进行元素的…

LruCache缓存

Lru算法&#xff1a; Lru 指的是“Least Recently Used-近期最少使用算法”。 1、那么LruCache到底是什么呢&#xff1f; LruCache 是对限定数量的缓存对象持有强引用的缓存&#xff0c;每一次缓存对象被访问&#xff0c;都会被移动到队列的头部。当有对象要被添加到已经达到数…

LruCache 源码解析

1. 概述 对于 Android 开发者&#xff0c;LruCache 肯定不陌生&#xff0c;几乎所有的图片缓存框架都会用到它来实现内存缓存等&#xff0c;可见 LruCache 在 Android 开发中的重要性。LRU 是 Least Recently Used 的缩写&#xff0c;近期最少使用的意思。当我们进行缓存的时候…

LruCache

LruCache这个类是通过Glide得知的&#xff0c;不过它是自己又基于LRU算法自己写了个LruCache工具类&#xff0c;不过基本原理类似&#xff0c;都是基于LRU算法实现的 1.来源 一般来说&#xff0c;缓存策略主要包含缓存的添加、获取和删除这三类操作。如何添加和获取缓存这个比…

Android基础-LruCache原理解析

一、Android中的缓存策略 一般来说&#xff0c;缓存策略主要包含缓存的添加、获取和删除这三类操作。如何添加和获取缓存这个比较好理解&#xff0c;那么为什么还要删除缓存呢&#xff1f;这是因为不管是内存缓存还是硬盘缓存&#xff0c;它们的缓存大小都是有限的。当缓存满了…

LRUCache详解

1.概念 LRU是Least Recently Used的缩写&#xff0c;意思是最近最少使用&#xff0c;它是一种Cache替换算法。 Cache的容量有限&#xff0c;因此当Cache的容量用完后&#xff0c;而又有新的内容需要添加进来时&#xff0c; 就需要挑选并舍弃原有的部分内容&#xff0c;从而腾出…

LRUCache 详解

LRU算法详解 一、什么是 LRU 算法 就是一种缓存淘汰策略。 计算机的缓存容量有限&#xff0c;如果缓存满了就要删除一些内容&#xff0c;给新内容腾位置。但问题是&#xff0c;删除哪些内容呢&#xff1f;我们肯定希望删掉哪些没什么用的缓存&#xff0c;而把有用的数据继续…

LRU Cache

前言 哈喽&#xff0c;各位小伙伴大家好&#xff0c;本章内容为大家介绍计算机当中为了提高数据相互传输时的效率而引进的一种重要设计结构叫做LRU Cache,下面将为大家详细介绍什么是LRU Cache,以及它是如何是实现的&#xff0c;如何提升效率的。 1.什么是LRU Cache? LRU是L…

uniapp日历原生插件

<template><!-- 打卡日历页面 --><view classall><view class"bar"><!-- 上一个月 --><view class"previous" click"handleCalendar(0)"><button class"barbtn">上一月</button><…

微信小程序使用日历插件

一&#xff0c;添加插件 1&#xff0c;在你的小程序关联的微信公众平台打开 设置》第三方服务》添加插件 2&#xff0c;直接AppID&#xff08;wx92c68dae5a8bb046&#xff09;搜索到该插件并申请授权&#xff0c;授权成功即可在小程序使用 二&#xff0c;小程序使用插件 app…