二叉搜索树的删除操作可以交换吗_一文看懂数据结构中的树
- 树的定义
- 树的结构
- 工作原理
- 代码实现
现在就开始学习吧 :)
树的定义
通常对编程新手来说,线性数据结构比树和图要更好理解。我们此处所说的树,即是以层次化方式组织和存放数据的特定数据结构。实例解析为了理解“层次化”的意思,我们以家谱为例:里面有祖父母、父母、孩子、兄弟姐妹。这就是用层次化的模式来构建家谱。上图就是我的家谱。Tossico,Akikazu,Hitomi和Takemi作为我的祖父母和外祖父母处于最顶层。Toshiaki 和 Juliana是我父母。TK,Yuji,Bruno 和 Kaio 则是我和我的的兄弟姐妹们。公司组织也是类似的层次化结构HTML的文档模型对象 (DOM) 就是一棵树
名词定义树(tree):是以边(edge)相连的结点(node)的集合,每个结点存储对应的值(value/data),当存在子结点时与之相连。根结点(root):是树的首个结点,在相连两结点中更接近根结点的成为父结点(parent node),相应的另一个结点称为子结点(parent node)。边(edge):所有结点都由边相连,用于标识结点间的关系。边是树中很重要的一个概念,因为我们用它来确定节点之间的关系。叶子结点(Leaves):是树的末端结点,他们没有子结点,就像真实的树那样 ,由根开始,伸展枝干,到叶为止。树高(height)与结点深度(depth)也是很重要的概念。树高:是由根结点出发,到子结点的最长路径长度。结点深度:是指对应结点到根结点路径长度。
二叉树
现在来探讨一种特殊的树结构-二叉树(binary tree),它每个节点最多有两个子结点,亦称左孩子和右孩子。
在计算机科学中,二叉树是一种“树”数据结构,树上的每个节点最多有两个孩子,分别为左孩和右孩。——维基百科
来看一个二叉树的实例。动手写二叉树首先明确我们要实现的对象是一个结点集合,每个结点有三个属性:值(value), 左孩子(left_child)和右孩子(right_child)。写出来会是这个样子:我们写了一个BinaryTree类,在初始化实际对象的时候传入对应值,并在此时还没有子结点的情况下将左右孩子设为空。为什么要这么做呢?因为当我们创建节点的时候,它还没有孩子,我们只有节点数据。让我们测试一下:下面到了插入结点的操作:在树还没有对应子结点时新建结点,并赋值给现有结点对应变量。否则,新建结点连接并替换掉现有位置子结点。画出来是这个样子:
相应代码(左右相同):为了进一步测试,让我们构建一个更复杂一些的树:
这棵树共有六个结点,其中结点b没有左孩子。对应初始化并插入结点的代码如下:下一步让我们看看如何对树进行遍历。一般来讲我们有两种遍历方式:深度优先遍历(DFS) 和 广度优先遍历(BFS),前者沿着特定路径遍历到根结点再转换临近路径继续遍历,后者逐层遍历整个树结构。来看具体的例子:
深度优先遍历 (DFS)
DFS 会沿特定路径遍历到叶子结点再回溯 (backtracking) 进入临近路径继续遍历。以下面的树结构为例:
在输出遍历结果时,据父结点值相对子结点输出顺序的不同,深度优先遍历又可细分为先序、中序和后序遍历三种情况。先序遍历即直接按照我们对结点的访问顺序输出遍历结果即实现,父结点值被最先输出。代码:中序遍历中序遍历输出结果为:3–2–4–1–6–5–7。左孩子值最先输出,然后是父结点,最后是右孩子。对应代码如下:后序遍历后序遍历输出结果为:3–4–2–6–7–5–1.左右孩子值依次输出,最后是父结点,对应代码如下:广度优先搜索 (BFS)BFS :按照结点深度逐层遍历树结构。再拿上面的图来实际解释这种方法:
逐层每层从左到右进行遍历,对应遍历结果为:1–2–5–3–4–6–7。对应代码如下:你应该已经注意到了,我们要借助先进先出(FIFO)的队列(queue)结构完成操作,具体的出入队列顺序如下图所示:
二叉搜索树
二叉搜索树又名有序二叉树,结点元素按固定次序排布,使得我们可以在进行查找等操作时使用二分搜索提高效率。——维基百科
它最明显的特征是父结点值大于左子树任意结点值,小于右子树任意结点值。
上图以三个二叉树为例,哪个才是正确的呢?
- A 左右子树需要进行交换。
- B 满足条件,是二叉搜索树。
- C 值为4的结点需要移至3的右孩子处
接下来进行二叉搜索插入、结点检索、结点删除以及平衡的解释。插入假设以这种顺序插入结点: 50, 76, 21, 4, 32, 100, 64, 52。50会是我们初始的根结点。再依次进行如下操作:
- 76 大于50,置于右边
- 21 小于 50, 置于左边
- 4 置于21左边
最终一气呵成我们会得到下面这棵树:发现规律了么?像开车一样,从根结点驶入,待插入值大于当前结点值向右开否则向左开知道找到空位停车入库。(嘀嘀嘀,老司机)代码实现也很简单:这个算法最牛逼的地方在于他的递归部分,你知道是哪几行吗?结点检索其实结合我们的插入操作,检索的方法就显而易见,依旧从根结点开始,小于对应结点值左转,大于右转,等于报告找到,走到叶子结点都没找到 gg,就报没有该元素。例如我们想知道下图中有没有52这个值:代码如下:删除: 移除并重构删除操作要更复杂一些,因为要处理三种不同情况:
- 情景 #1:叶子结点
是最简单的情况,直接删除就好.
- 情景 #2:只有左孩子或右孩子
该情景等价于链表上的结点删除,把当前结点删除并让其子结点替换自己原来位置。
- 情景 #3:同时具有左右孩子的结点
找到该结点右子树中最小值所在的结点,剔除要删除的当前结点并把最小值结点提升到空缺位置。一些别的骚操作清零:将三个属性全部置None即可。找到最小值:从根节点开始,一直左转,直到找不到任何结点为止,此时我们就找到了最小值。恭喜你学完本篇内容!数据结构中的树的内容大致如此,赶紧收藏起来吧
投稿:黄猛击参考:https://medium.freecodecamp.org/all-you-need-to-know-about-tree-data-structures-bceacb85490c
名师出高徒。想和领域大牛一起学人工智能?
二叉搜索树的删除操作可以交换吗_一文看懂数据结构中的树相关推荐
- 二叉搜索树的删除操作可以交换吗_JavaScript数据结构 — 二叉搜索树(BST)ES6实现...
1. 概述 最基本的数据结构是向量和链表,为了将二者的优势结合起来,我们引入了二叉树,可以认为二叉树是列表在维度上的拓展.而今天要介绍的二叉搜索树(BST)则是在形式上借鉴了二叉树,同时也巧妙借鉴了有 ...
- 7-2 二叉搜索树的删除操作
给出一棵二叉搜索树(没有相同元素), 请输出其删除部分元素之后的层序遍历序列. 删除结点的策略如下: 如果一个结点是叶子结点,则直接删除: 如果一个结点的左子树不为空, 则将该结点的值设置为其左子树上 ...
- Python实现二叉搜索树的删除功能
Python实现二叉搜索树的删除功能 二叉搜索树(二叉查找树,Binary Search Tree)又称为排序二叉树.有序二叉树. 二叉搜索树的实现可以参考:https://blog.csdn.net ...
- 08_Python算法+数据结构笔记-二叉搜索树查询/删除-AVL树旋转/插入/应用-贪心算法
b站视频:路飞IT学城 清华计算机博士带你学习Python算法+数据结构_哔哩哔哩_bilibili #71 二叉搜索树:查询 import randomclass BiTreeNode:def __ ...
- 数据结构 二叉搜索树的删除
文章目录 概述 待删除的结点没有子树 待删除的结点仅有一颗子树 待删除的结点有两颗子树 C代码实现 概述 这是一篇短文,专门考究一下二叉搜索树的删除. 二叉搜索树的建立非常简单,如果不熟悉的见此文 树 ...
- 二叉搜索树的查询操作《算法导论》12.2
我们可以在O(h)时间内完成二叉搜索树的查找.最大值.最小值.给定节点的前驱.后继操作,h代表树的高度.下面是用C++实现的<算法导论>12.2节伪代码,附习题解答. #include & ...
- 二叉搜索树的删除_LeetCode109.有序链表转换二叉搜索树
点击上方"蓝字",发现更多精彩. 01PART二叉搜索树二叉查找树又称二叉搜索树或者二叉排序树:它可以是一个空树或者是一个二叉树,既有链表的快速插入与删除的特点,又有数组快速查找的 ...
- 最适合新手看的平衡二叉搜索树(BBST)的创建,包含详细过程,一看就会(C++版)
写在前面:本人大二小白,本篇文章是我第一次写博客,用来记录我的学习过程,我想将我在学习中遇到的各种的问题和困难写下来,希望大家能够不要犯同样的错误.我会尽可能的详细的把每一个步骤都解释清楚,那么废话不 ...
- angular 字符串转换成数字_一文看懂Python列表、元组和字符串操作
好文推荐,转自CSDN,原作星辰StarDust,感觉写的比自己清晰-大江狗荐语. 序列 序列是具有索引和切片能力的集合. 列表.元组和字符串具有通过索引访问某个具体的值,或通过切片返回一段切片的能力 ...
最新文章
- 技术图文:举例详解Python中 split() 函数的使用方法
- 杨植麟:28 岁青年科学家,开挂人生的方法论
- Python拼接多张图片
- 调研机构称明年全球数据中心基础设施支出将增长6%
- python竞赛_浅谈Python在信息学竞赛中的运用及Python的基本用法
- js修改video的source_利用 javascript MediaSource 将 HTML video标签的src转成加载blob
- 《最后期限》阅读笔记2
- 域对抗自适应算法的设计、不足与改进(Domain Adversarial Learning)
- C++bidirectional dijkstra双向最短路径算法(附完整源码)
- css 动态rem_HTML + CSS 为何得不到编程界的认可?
- QT中ui更改后不能更新的解决方法
- java运行python脚本_用Java运行Python脚本
- 手机app性能测试简介了解
- cors js解决js跨域问题
- java 以2为底的对数_如何计算Java中以整数为底的对数2?
- 苹果回应巴西政府禁止销售不附赠充电器的iPhone;小米造车新进展;国内首家以数据服务为核心的央企数据中台上线 | EA周报...
- android zip格式的ndk,Android 使用NDK (JNI)容易解压7z压缩文件
- [转]和《红楼梦》咏菊花诗十二首
- 如何针对时间片论法进行优化
- 过滤器VS拦截器的4个区别,看完豁然开朗!
热门文章
- 二分答案——数列分段 Section II(洛谷 P1182)
- PAT乙级(1023 组个最小数)
- 2021年11月国产数据库排行榜:openGauss闯入前三,Kingbase流行度与日俱增,TDengine厚积薄发
- Oracle 19.6 的有趣BUG:可能引发 CLOB 存储数据的丢失
- 承上 DBlink 与 SCN | 新增视图找出外部 SCN 跳变
- 想了解 spring-cloud-kubernetes,那就先来实战一把官方demo
- k8s源码Client-go中Reflector解析
- 【华为云技术分享】云小课 | 如何通过虚拟私有云保障服务安全
- 【Python算法】分类与预测——logistic回归分析
- 华为云ROMA,联接企业应用的现在与未来