二叉搜索树
创始人
2024-01-16 23:06:07
0

文章目录

  • 二叉搜索树
  • 1. 概念
  • 2. 模拟实现二叉搜索树
    • 2.1 准备工作 创建类
    • 2.2 查找方法
    • 2.3 插入方法
    • 2.4 删除方法
  • 3. 性能分析

二叉搜索树


前言 :

在这里插入图片描述

1. 概念


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

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

在这里插入图片描述

概念啥的看看就行了,之前二叉树的时候可能就已经见过了, 下面我们直接来实现我们自己的二叉搜索树

2. 模拟实现二叉搜索树

2.1 准备工作 创建类


这里我们创建一个 BinarySearchTree 和 内部类 TreeNode
在这里插入图片描述

2.2 查找方法

在这里插入图片描述


代码实现 :

查找功能就完成了,下面完成插入方法

2.3 插入方法

在这里插入图片描述


补充: 这里我们 假设我们的二叉搜索树是一颗完全二叉树,那么这里我们插入的时间复杂度是不是就是O(logN)

在这里插入图片描述


单分支的情况 加 了解 AVL 树
在这里插入图片描述


补充 : 这里忘记 讲 了 这里 二叉搜索树是空树的情况,那么我们直接让 root = new TreeNode(val) 即可,创建第一个节点


最终代码 :

 public boolean insert(int val) {if (root == null) {root = new TreeNode(val);}TreeNode cur = root;//定义一个 parent 指向 cur的 上一个根节点TreeNode parent = null;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;}}// 此时判断 当前的val 是大于 parent.val 还是小于if (parent.val < val) {// 此时 根据二叉搜索树的性质大于根 放在右树parent.right = new TreeNode(val);}if (parent.val > val) {// 此时 val 小于 parent.val 插入左树parent.left = new TreeNode(val);}return true;}

下面就来学习一下,二叉搜索树中难一点的方法删除

2.4 删除方法

删除操作,算我们实现二叉搜索树中唯一难一点的操作这里需要分三种情况

图一:

在这里插入图片描述


图二 : cur.left == null

在这里插入图片描述


图三 : cur.right == null

在这里插入图片描述


图四 : cur.left != null && cur.right != null

在这里插入图片描述


这里在右树中找最小的 可以自己画图分析 ,因为是一样的, 这里就留一个作业, 或者看下面的代码实现, 我们图是以找左树最大的,代码以找右树最小的 。


图一 :
在这里插入图片描述


图二 :

在这里插入图片描述


删除总代码:

 // 写一个方法找到我们需要删除的节点 和 根节点public void remove(int key) {//找 parent 和 cur 节点TreeNode cur = root;TreeNode parent = null;while (cur != null) {if (cur.val < key) {parent = cur;cur = cur.right;} else if (cur.val > key) {parent = cur;cur = cur.left;} else {// 此时找到了我们的 cur ,和 parentremoveNode(cur, parent);break;}}}public void removeNode(TreeNode cur, TreeNode parent) {// 1. 当 cur.left == null  的情况if (cur.left == null) {// 此时又分为三种情况if (cur == root) {root = root.right;// cur.left == null ,所以直接让 root 等于右树} else if (parent.left == cur) {// 根据图的分析,parent.left = cur.right;} else {// 此时 parent.right = curparent.right = cur.right;}} else if (cur.right == null) {// 此时 cur.right 同样有三种情况if (cur == root) {root = root.left;} else if (parent.left == cur) {parent.left = cur.left;} else {// parent.right = curparent.right = cur.left;}} else {// cur.left != null && cur.right != null  这里我们使用方法二// 在cur的右树中找 最小的TreeNode parentDummy = cur;TreeNode curDummy = cur.right;while (curDummy.left != null) {parentDummy = curDummy;curDummy = curDummy.left;}cur.val = curDummy.val;// 此时找到了最小的 判断两种情况即可//  curDummy.left == nullif (parentDummy.left == curDummy) {parentDummy.left = curDummy.right;} else {//parentDummy.right = curDummyparentDummy.right = curDummy.right;}}}

此时我们的二叉搜索的 查找新增删除方法就完成了.

附上代码:

public class BinarySearchTree {static class TreeNode {public int val;public TreeNode left;public TreeNode right;public TreeNode(int val) {this.val = val;}}public TreeNode root;public TreeNode search(int key) {TreeNode cur = root;while (cur != null) {if (cur.val < key) {// 此时 key 大于 根进入 右树找cur = cur.right;} else if (cur.val > key) {// 此时 ken 小于 根进入 左树找cur = cur.left;} else {// 此时说明找到了 返回 当前节点地址;return cur;}}// 此时说明没有找到return null;}public boolean insert(int val) {if (root == null) {root = new TreeNode(val);}TreeNode cur = root;//定义一个 parent 指向 cur的 上一个根节点TreeNode parent = null;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;}}// 此时判断 当前的val 是大于 parent.val 还是小于if (parent.val < val) {// 此时 根据二叉搜索树的性质大于根 放在右树parent.right = new TreeNode(val);}if (parent.val > val) {// 此时 val 小于 parent.val 插入左树parent.left = new TreeNode(val);}return true;}// 写一个方法找到我们需要删除的节点 和 根节点public void remove(int key) {//找 parent 和 cur 节点TreeNode cur = root;TreeNode parent = null;while (cur != null) {if (cur.val < key) {parent = cur;cur = cur.right;} else if (cur.val > key) {parent = cur;cur = cur.left;} else {// 此时找到了我们的 cur ,和 parentremoveNode(cur, parent);break;}}}public void removeNode(TreeNode cur, TreeNode parent) {// 1. 当 cur.left == null  的情况if (cur.left == null) {// 此时又分为三种情况if (cur == root) {root = root.right;// cur.left == null ,所以直接让 root 等于右树} else if (parent.left == cur) {// 根据图的分析,parent.left = cur.right;} else {// 此时 parent.right = curparent.right = cur.right;}} else if (cur.right == null) {// 此时 cur.right 同样有三种情况if (cur == root) {root = root.left;} else if (parent.left == cur) {parent.left = cur.left;} else {// parent.right = curparent.right = cur.left;}} else {// cur.left != null && cur.right != null  这里我们使用方法二// 在cur的右树中找 最小的TreeNode parentDummy = cur;TreeNode curDummy = cur.right;while (curDummy.left != null) {parentDummy = curDummy;curDummy = curDummy.left;}cur.val = curDummy.val;// 此时找到了最小的 判断两种情况即可//  curDummy.left == nullif (parentDummy.left == curDummy) {parentDummy.left = curDummy.right;} else {//parentDummy.right = curDummyparentDummy.right = curDummy.right;}}}public void inorder(TreeNode root) {if (root == null) {return;}// 中序遍历 左 -> 根 -> 右inorder(root.left);System.out.print(root.val + " ");inorder(root.right);}
}


下面我们测试一下

在这里插入图片描述

完美

3. 性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。

对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。

但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树

在这里插入图片描述


最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:

最差情况下,二叉搜索树退化为单支树,其平均比较次数为:

问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插入关键码,都可以

是二叉搜索树的性能最佳?

这里学习二叉搜索树 ,主要是为下文的 SetMap 做准备

TreeMap 和 TreeSet 即 java 中利用搜索树实现的 Map 和 Set;实际上用的是红黑树,而红黑树是一棵近似平衡的

二叉搜索树,即在二叉搜索树的基础之上 + 颜色以及红黑树性质验证,这里红黑树比较难,需要我们知识的沉淀 ,那么再后续再来说我们的AVL树和红黑树…

下文 : Map 和 Set

相关内容

热门资讯

事故索赔申请书 事故索赔申请书范文(精选5篇)  随着社会在进步,申请书与我们不再陌生,申请书不同于其他书信,是一种...
入团申请书 入团申请书模板400字(通用15篇)  在当今社会生活中,很多场合都离不了申请书,利用申请书我们可以...
困难救助申请书 困难救助申请书(精选7篇)  在眼下市场经济活跃的社会,我们会使用上申请书,不同的使用场景有不同的申...
助学金申请表申请理由模板 助学金申请表申请理由模板  一、国家助学金的基本申请条件  ①热爱社会主义祖国,拥护中国共产党的领导...
售后申请报告范文18篇 售后申请报告范文 第一篇亲爱的领导:从我踏出校门的那一刻,满怀壮志的灵魂早已被阴暗的墙壁磨损殆尽。由...
签证专员辞职申请书 签证专员辞职申请书  随着时代在进步,我们会经常使用申请书,请注意不同种类的申请书有着不同的格式。写...
工伤职工申请补偿书范文通用1... 工伤职工申请补偿书范文 第一篇(一)治(医)疗费。治疗工伤所需费用必须符合工伤保险诊疗项目目录、工伤...
村干部入党申请书 最新村干部入党申请书(通用4篇)  在当今社会高速发展的今天申请书起到的作用越来越大,申请书可以使我...
案件答疑申请书范文(推荐5篇... 案件答疑申请书范文 第一篇【申请人理由】上诉人在《民事上诉状》已上诉:一审法官、一审判决书混淆了原告...
申请仲裁书 申请仲裁书模板  申请人:名称:________ 地址:________________  法定代表...
助学金申请理由简短 助学金申请理由简短200字  新的学期开始了,又到申请助学金的时候,那么助学金申请理由怎么写?本文是...
向法院申请强制执行申请书 向法院申请强制执行申请书(精选12篇)  现今社会公众的追求意识不断提升,申请书起到的作用越来越大,...
技术转让专利申请权合同 技术转让(专利申请权)合同合同编号:_________项目名称:_________受让方(甲方):_...
济南公租房申请条件   济南市明确了公租房的申请条件和流程,其中申请条件又分为家庭申请和单身申请、济南市户籍申请和非济南...
大学生贫困助学金申请书 大学生贫困助学金申请书(精选10篇)  在这个高速发展的时代,申请书在生活中的使用越来越广泛,写申请...
职工病假申请书 职工病假申请书范文  我们眼下的社会,需要使用申请的场合越来越多,我们在写申请书的时候要注意态度要诚...
农村土地复垦申请书 农村土地复垦申请书精选  xxx镇政府:  xxx市土地局:  xxx镇xx村位于同河南岸,地处丘陵...
助学金申请书格式 助学金申请书格式(精选15篇)  在眼下市场经济活跃的社会,申请书应用范围广泛,正确运用申请书可以达...
关于企业法人变更申请书 关于企业法人变更申请书  一、申请书的注意事项  (1)申请的事项要写清楚、具体,涉及的数据要准确无...
车费报销申请书 车费报销申请书  篇一:车费报销申请书尊敬的公司领导:  您好!我是公司文员xx。根据公司的'安排,...