JavaSE 搜索树

目录

  • 1 概念
  • 2 操作
    • 2.1 查找
    • 2.2 插入
    • 2.3 删除
  • 3 性能分析
  • 4 和 java 类集的关系

1 概念

二叉搜索树 又称 二叉排序树,它是一棵空树,或者是具有以下性质的二叉树:

  1. 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值;
  2. 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。
  3. 它的左右子树也分别为二叉搜索树

你会发现它中序遍历的结果就是有序的。
如下图所示就是一颗二叉搜索树:
在这里插入图片描述

2 操作

2.1 查找

在这里插入图片描述
具体实现代码示例如下所示:

package bstree;class BinarySearchTree{static class BSNode{public int val;public BSNode left;public BSNode right;public BSNode(int val) {this.val = val;}}public BSNode root = null;public BSNode search(int val){if(root == null) return null;BSNode cur = root;while (cur != null){if(cur.val == val){return cur;}else if(cur.val > val){cur = cur.left;}else{cur = cur.right;}}return null;}}public class TestDemo {public static void main(String[] args) {}
}

2.2 插入

  1. 如果树为空树,即根 == null,直接插入。
    在这里插入图片描述
  2. 如果树不是空树,按照查找逻辑确定插入位置,插入新结点。
    在这里插入图片描述
    具体实现代码示例如下所示:
package bstree;class BinarySearchTree{static class BSNode{public int val;public BSNode left;public BSNode right;public BSNode(int val) {this.val = val;}}public BSNode root = null;public BSNode search(int val){if(root == null) return null;BSNode cur = root;while (cur != null){if(cur.val == val){return cur;}else if(cur.val > val){cur = cur.left;}else{cur = cur.right;}}return null;}public boolean insert(int val){BSNode bsNode = new BSNode(val);if(root == null){root = bsNode;return true;}BSNode cur = root;BSNode parent = null;while(cur != null){if(cur.val == val){return false;}else if(cur.val > val){parent = cur;cur = cur.left;}else{parent = cur;cur = cur.right;}}if(parent.val < val){parent.right = bsNode;}else{parent.left = bsNode;}return true;}}public class TestDemo {public static void preOrder(BinarySearchTree.BSNode root){if(root == null){return;}System.out.print(root.val+" ");preOrder(root.left);preOrder(root.right);}public static void inOrder(BinarySearchTree.BSNode root){if(root == null){return;}inOrder(root.left);System.out.print(root.val+" ");inOrder(root.right);}public static void main(String[] args) {BinarySearchTree binarySearchTree = new BinarySearchTree();binarySearchTree.insert(4);binarySearchTree.insert(3);binarySearchTree.insert(1);binarySearchTree.insert(15);binarySearchTree.insert(11);preOrder(binarySearchTree.root);System.out.println();inOrder(binarySearchTree.root);System.out.println();try {BinarySearchTree.BSNode ret = binarySearchTree.search(4);System.out.println(ret.val);}catch (NullPointerException e){System.out.println("没有找到当前的节点..........");e.printStackTrace();}}
}

2.3 删除

前提是删除这个节点之后,整棵树还是一棵二叉搜索树。
删除思路:
设待删除结点为 cur, 待删除结点的双亲结点为 parent。
则分为下面三种情况:

  1. cur.left == null

cur 是 root,则 root = cur.right
cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
cur 不是 root,cur 是 parent.right,则 parent.right = cur.right

  1. cur.right == null

cur 是 root,则 root = cur.left
cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
cur 不是 root,cur 是 parent.right,则 parent.right = cur.left

  1. cur.left != null && cur.right != null
  1. 如果像原来那样删除,那么一个节点就会出现两个父亲节点?
    需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键值最小),用它的值填补到被删除节点中,再来处理该结点的删除问题。
  2. 我们怎么知道放谁上去?
    当前需要删除的节点的左边找最大的,右边找最小的。

具体实现代码示例如下所示:

package bstree;class BinarySearchTree {static class BSNode {public int val;public BSNode left;public BSNode right;public BSNode(int val) {this.val = val;}}public BSNode root = null;public BSNode search(int val) {if (root == null) return null;BSNode cur = root;while (cur != null) {if (cur.val == val) {return cur;} else if (cur.val > val) {cur = cur.left;} else {cur = cur.right;}}return null;}public boolean insert(int val) {BSNode bsNode = new BSNode(val);if (root == null) {root = bsNode;return true;}BSNode cur = root;BSNode parent = null;while (cur != null) {if (cur.val == val) {return false;} else if (cur.val > val) {parent = cur;cur = cur.left;} else {parent = cur;cur = cur.right;}}if (parent.val < val) {parent.right = bsNode;} else {parent.left = bsNode;}return true;}public void remove(int val) {if (root == null) return;BSNode cur = root;BSNode parent = null;while(cur !=null){if (cur.val == val) {removeNode(parent,cur,val);} else if (cur.val < val) {parent = cur;cur = cur.right;} else {parent = cur;cur = cur.left;}}}public void removeNode(BSNode parent,BSNode cur,int val){if(cur.left == null){if(cur == root){root = cur.right;}else if(parent.left == cur){parent.left = cur.right;}else if(parent.right == cur){parent.right = cur.right;}}else if(cur.right == null){if(cur == root){root = cur.left;}else if(parent.left == cur){parent.left = cur.left;}else if(parent.right == cur){parent.right = cur.left;}}else{//这里采取的是右边找最小的方法BSNode targetParent = cur;BSNode target = cur.right;while(target.left != null){targetParent = target;target = target.left;}//target指向的节点就是 右边的最小值cur.val = target.val;if(target == targetParent.left){targetParent.left = target.right;}else{targetParent.right = target.right;}}}}public class TestDemo {public static void preOrder(BinarySearchTree.BSNode root){if(root == null){return;}System.out.print(root.val+" ");preOrder(root.left);preOrder(root.right);}public static void inOrder(BinarySearchTree.BSNode root){if(root == null){return;}inOrder(root.left);System.out.print(root.val+" ");inOrder(root.right);}public static void main(String[] args) {BinarySearchTree binarySearchTree = new BinarySearchTree();binarySearchTree.insert(4);binarySearchTree.insert(3);binarySearchTree.insert(1);binarySearchTree.insert(15);binarySearchTree.insert(11);preOrder(binarySearchTree.root);System.out.println();inOrder(binarySearchTree.root);System.out.println();binarySearchTree.remove(15);System.out.println("=============删除===============");preOrder(binarySearchTree.root);System.out.println();inOrder(binarySearchTree.root);System.out.println();try {BinarySearchTree.BSNode ret = binarySearchTree.search(4);System.out.println(ret.val);}catch (NullPointerException e){System.out.println("没有找到当前的节点..........");e.printStackTrace();}}
}

3 性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。
但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:
在这里插入图片描述
最优情况下: 二叉搜索树为完全二叉树,其比较次数为:O(log2^n)
最差情况下: 二叉搜索树退化为单支树,其比较次数为:O(n)。
问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插入关键码,都可以是二叉搜索树的性能最佳?

4 和 java 类集的关系

TreeMap 和 TreeSet 即 java 中利用搜索树实现的 Map 和 Set;实际上用的是红黑树,而红黑树是一棵近似平衡的二叉搜索树,即在二叉搜索树的基础之上 + 颜色以及红黑树性质验证,关于红黑树的内容在后边笔记中再进行描述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/234440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js使用promise对象达到promise waiting

async getInfoFormName() {return new Promise((resolve, reject) > {let infoForm: string;if (this.showBox "basic-info-box") {infoForm "basicInfoForm";} else {infoForm "extendInfoForm";}resolve(infoForm);});} 使用这个Priomi…

[Java][File]文件的创建与删除

对一个File类型的对象而言 1.创建一个新的空的文件 createNewFile 2.制作单级文件夹 mkdir 3.制作多级文件夹 mkdirs 4.删除文件、空文件夹 delete 注意&#xff1a;这个方法不会走回收站的 import java.io.File; import java.io.IOException;public class Main{public static …

Logistic Regression逻辑线性回归(基于diabetes数据集)

目录 介绍&#xff1a; 1、Confusion Matrix&#xff1a; 2、ROC&#xff08;Receiver Operating Characteristic&#xff09; 一、数据处理 二、建模 三、 confusion_matrix 四、 ROC&#xff08;Receiver Operating Characteristic&#xff09; 介绍&#xff1a; L…

class085 数位dp-下【算法】

class085 数位dp-下【算法】 code1 P2657 [SCOI2009] windy 数 // windy数 // 不含前导零且相邻两个数字之差至少为2的正整数被称为windy数 // windy想知道[a,b]范围上总共有多少个windy数 // 测试链接 : https://www.luogu.com.cn/problem/P2657 // 请同学们务必参考如下代码…

好习惯的重要性

养成习惯的五个步骤 提高认识 引导孩子对养成某个习惯产生兴趣明确规范 让孩子对养成某个好习惯的具体规范持久训练 坚持不懈的行为规范&#xff0c;让孩子由被动到主动再到自动及时评估 让孩子在成功的体验中养成良好习惯形成环境 让家庭生活和学校环境乃至社会风气成为孩子养…

7款创意性前端源码特效资源分享(附在线预览效果)

分享7款非常不错炫酷的前端特效源码 其中包含css动画特效、js原生特效、svg特效等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 CSS绘制iPhone 14带动态岛 纯CSS绘制iPhone 14带动态岛模型 运行初始化时还附带出场动画 …

微信小程序动态导航栏(uniapp + vant)

本文使用到vant的van-tabbar组件来实现 一、uniapp整合vant ui vant小程序版本:https://vant-contrib.gitee.io/vant-weapp/#/home 注:vant并没有uniapp的版本,所以此处是引入小程序版本的ui 1. 下载vant编译后代码 https://github.com/youzan/vant-weapp/tree/dev/dist 2…

vue中对keep-alive的理解

vue中对keep-alive的理解 介绍使用方法参数解析使用示例 介绍 keep-alive是 Vue 内置的一个组件&#xff0c;可以使被包含的组件保留状态&#xff0c;或避免重新渲染。它有两个属性: include(包含的组件缓存) 与 exclude(排除的组件不缓存&#xff0c;优先级大于include) 。 使…

CentOs7.x安装部署SeaTunnelWeb遇到的坑

CentOs7.x安装部署SeaTunnelWeb遇到的坑 文章目录 1. 环境2. SeaTunnel安装部署2.1下载安装包2.2 设置环境变量2.3 安装连接器插件2.4 拷贝jar包到lib下2.5 启动命令2.6 执行官方client提交任务demo 3. SeaTunnel-Web安装部署3.1 下载安装包3.2 初始化数据库脚本或修改配置appl…

element plus 表格el-table行多选单选

1 行多选-点击checkbox 添加一个 el-table-column&#xff0c;设 type 属性为 selection 即可 <template><div class"box"><el-table :data"tableData" selection-change"handleSelectionChange"><el-table-column type&…

【单调栈】LeetCode:1944队列中可以看到的人数

作者推荐 【贪心算法】【中位贪心】.执行操作使频率分数最大 题目 有 n 个人排成一个队列&#xff0c;从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights &#xff0c;每个整数 互不相同&#xff0c;heights[i] 表示第 i 个人的高度。 一个人能 看到 他右边另一个人…

计算机网络 运输层下 | TCP概述 可靠传输 流量控制 拥塞控制 连接管理

文章目录 3 运输层主要协议 TCP 概述3.1 TCP概述 特点3.2 TCP连接RSVP资源预留协议 4 TCP可靠传输4.1 可靠传输工作原理4.1.1 停止等待协议4.1.2 连续ARQ协议 4.2 TCP可靠通信的具体实现4.2.1 以字节为单位的滑动窗口4.2.2 超时重传时间的选择4.2.3 选择确认SACK 5 TCP的流量控…

(C)一些题14

1.下列定义不正确的是&#xff08;C A .# define PI 3.141592 C . int max ( x , y ); int x , y ;{} B .# define S 345 D . static char c ; 函数没有定义x&#xff0c;y的类型 2&#xff0e;以下程序段的输出结果为&#xff08;D char c []" abc "; int i …

边缘计算有哪些常用场景?TSINGSEE边缘AI视频分析技术行业解决方案

随着ChatGPT生成式人工智能的爆发&#xff0c;AI技术在业界又掀起一波新浪潮。值得关注的是&#xff0c;边缘AI智能也在AI人工智能技术进步的基础上得到了快速发展。IDC跟踪报告数据显示&#xff0c;2021年我国的边缘计算服务器整体市场规模达到33.1亿美元&#xff0c;预计2020…

前端面试题(计算机网络):GET和POST的请求的区别是什么?

声明&#xff1a;什么是幂等请求&#xff1f;答&#xff1a;不管对同一资源请求多少次返回的结果都相同 Post 和 Get 是 HTTP 请求的两种方法&#xff0c;其区别如下&#xff1a; 应用场景&#xff1a; GET 请求是一个幂等请求&#xff0c;一般 Get 请求用于对服务器资源不会…

2023年中国法拍房用户画像和数据分析

法拍房主要平台 法拍房主要平台有3家&#xff0c;分别是阿里、京东和北交互联平台。目前官方认定纳入网络司法拍卖的平台共有7家&#xff0c;其中阿里资产司法拍卖平台的挂拍量最大。 阿里法拍房 阿里法拍房数据显示2017年&#xff0c;全国法拍房9000套&#xff1b;2018年&a…

HuatuoGPT模型介绍

文章目录 HuatuoGPT 模型介绍LLM4Med&#xff08;医疗大模型&#xff09;的作用ChatGPT 存在的问题HuatuoGPT的特点ChatGPT 与真实医生的区别解决方案用于SFT阶段的混合数据基于AI反馈的RL 评估单轮问答多轮问答人工评估 HuatuoGPT 模型介绍 HuatuoGPT&#xff08;华佗GPT&…

Web请求与响应

目录 Postman Postman简介 Postman的使用 请求 简单参数 实体参数 数组参数 集合参数 日期参数 Json参数 路径参数 响应 ResponseBody 统一响应结果 Postman Postman简介 postman是一款功能强大的网页调试与发送网页http请求的Chrome插件&#xff0c;常用于进行…

故障排查:shell脚本输出乱码

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录 故障详情故障原因解决方法iconv命令介绍 故障详情 最近的工作中遇到一…

从零学算法334

334.给你一个整数数组 nums &#xff0c;判断这个数组中是否存在长度为 3 的递增子序列。 如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k &#xff0c;使得 nums[i] < nums[j] < nums[k] &#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…