邓俊辉 数据结构二叉搜索树

二叉搜索树(概述 循关键码访问)

在这里插入图片描述
BST(二叉搜索树)形式上继承了二叉树,同时又借鉴了有序向量的特性,这特别体现在BST的子集BBST(平衡二叉搜索树)

问题:为什么说二叉树是列表的列表呢(by xiaoxiaolin)
答:这句话在《数据结构(上)》第五章 05A-1

描述一棵树的时候,只需要把每个节点的孩子描述清楚,这棵树就唯一确定了。因此树可以看作节点的列表,每个节点是children的列表。

例如tree = [[1,2,4], [], [], [], [3,5], []],表示这棵树有6个节点,0号节点有三个子节点,分别是1、2、4号节点……
在这里插入图片描述

(by yuantailing 老师)
你可以先考虑“一维的树”这个概念。“一维的树”就是说父亲只有一个儿子,(一叉树) 然后你把“一叉树”画出来,会发现“一叉树”就是列表(by LogM)
在这里插入图片描述在这里插入图片描述在这里插入图片描述

二叉搜索树(概述 中序)

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

二叉搜索树(算法及实现 查找)

在这里插入图片描述在这里插入图片描述
指针与引用之易混点辨析
最近学习搜索树时发现一些可能大家需要注意的地方,特别是“引用与指针”,现做一总结:

所谓引用,指给某个变量换一个名字,即新名字和原名字都代表内存的同一区域,调用者可通过它们的任意一个来改变其对应内存中的数据

所谓指针,指一个变量的内存地址,通过地址可以访问和修改对应的变量。

所谓指针变量,它是一个变量,也在内存中占据一定空间,但保存了某个变量的指针。

观察BST相关操作,我们会发现,search操作的返回值是一个引用,是一个指针变量的引用,这个指针变量,或者说这个指针变量保存的地址指向了找到的节点。那么我们为什么需要引用?因为我们需要得到找到节点的位置?不是,因为我们需要修改找到节点?也不是。上述2个功能,没有引用,也可以完成,因为有原指针变量保存的地址,在另一个函数中用临时变量保留这个指针变量,也即保留了地址,立即就能通过这个地址访问和修改地址对应的节点。那么引用到底是为了什么?教材或视频中都说为了后续操作,但未说具体什么操作,我想有人可能马上会说,当然是插入和删除,但是确切地说,不是删除,而是插入。

插入操作势必会给找到节点位置分配一个新节点,而这个分配节点的操作就会改变找到节点的位置,换句话说,插入操作需要修改的是地址,而不是找到的节点!如果你想修改某个普通变量,那么你需要引用这个变量,如果你想修改某个地址,那么你需要引用这个地址所被保存的变量,也就是指针变量,这就是引用指针(变量)的真正目的。至于删除操作为什么也使用引用,我想大概是为了统一操作接口的规范,但统一归统一,概念可不能混淆。

总的来说,引用指针(变量)的目的就是为了改变指针,而这个操作一般体现在分配新节点时,一旦分配了新节点,当前引用到的指针被改变,之后只需通过这个指针修改其指向的对象即可,而指针本身一般不再去改变。(by 不羁的逆袭)
在这里插入图片描述

二叉搜索树(算法及实现 插入)

在这里插入图片描述在这里插入图片描述
问题:
我有个小疑问:这里返回的hot为待插入节点e的父节点,,但是e可以作为左孩子或者右孩子接入,此处并没有明确给出是哪一种。
所以,BinNode()这个构造函数针对BST类做了重载吗?
比如,取出e的data和hot的data进行比较,选择到底是把e作为hot的左孩子还是右孩子。
一般来说,这之类的辅助功能到底是放在重构函数里面实现,还是放在这里的insert()函数里面实现?有没有可参考的标准呢?(by HelloZH )
答:第一个问题:没有

第二个问题:x是hot的哪个孩子就把e作为hot的哪个孩子

new BinNode(e, _hot) 只是把新建节点的 parent 设为 _hot ,没有把 _hot->?Child 设为新建的节点。

x 是 _hot->?Child 的左值引用,是在 x = … 这个等号把 _hot->?Child 设为新建的节点的。(by yuantailing 老师)
我明白了,因为search()返回的是&类型,所以修改x等价于修改了_hot->?child,所以
x=NewNode等价于 _hot->?child = new node
而右边new BinNode(e,_hot)实现的是:NewNode->parent = _hot
谢谢老师了!(by HelloZH )

二叉搜索树(算法及实现 删除)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
x的直接后继:先转向右子树,然后一直沿左子树下行
在这里插入图片描述
对removeAt()算法的一些想法
首先关于语句“((u==x)?u->rc:u->lc)=succ=w->rc”,我刚开始没看懂,后来仔细分析了才理解。我发现无论是教材或视频,邓公都一笔带过了,而讨论区又有一些对此有疑问的帖子,看来邓公的“显然”的确对一些初学者来说是不“显然”的啊,希望在教材以后的版本中能多加几句注释。其次我说下我对此句的理解,以便后来的同学作参考:

此处有两种情况,第1种情况,x也是w的父亲,也就是说u等于x,那么按照中序遍历,w若要作为x的直接后继必然是x的右孩子,第2种情况,u不是x,即x不是w的父亲,那么根据中序遍历,w必然是u的左孩子。然而无论何种情况, w不可能有左孩子,所以u的左或右孩子只能被w的右孩子(可能不存在)替代,同时接替者也被w的右孩子替代。需要注意的是,此时u的孩子指针改变,w不再是u的孩子,但是w的父指针仍然指向u,所以hot就可以通过w来记录被删节点的父亲,若接替者存在,就将其与hot连接,最后因为w仍然指向被删除节点的位置,释放w,删除完成。(by 不羁的逆袭 )
u不等于x:
在这里插入图片描述
u==x:被删除节点的右子树没有左孩子的情况
在这里插入图片描述

二叉搜索树(平衡 期望树高)

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

二叉搜索树(平衡 理想与适度)

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

二叉搜索树(平衡 等价变换)

在这里插入图片描述在这里插入图片描述在这里插入图片描述
还可以想象成一串珠子下面挂着风铃。提着 c 还是提着 v 的区别。

zig 是从提着 v 变成提着 c。
在这里插入图片描述

在这里插入图片描述
AVL:时间O(1) 操作次数 O(log n)
红黑树:时间O(1) 操作次数 O(1)

二叉搜索树(AVL树 适度平衡)

在这里插入图片描述
BST :二叉查找树,但是它的高度不能令人满意,CBT (完全二叉树)的高度最低,为logn,但是从BST转换到CBT的代价很高,所以我们要放宽标准,只需渐进意义的logn即可,即O(logn),此类树即为BBST(平衡二叉搜索树),该类树即使不满足平衡标准,但是可以用极小的代价,通过等价变换,不超过O(logn)拉回到BBST,BBST: 1: 如何判断失衡 2: 如何进行再平衡
AVL就是一种BBST

二叉搜索树(AVL树 适度平衡)

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

二叉搜索树(AVL树 重平衡)

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

二叉搜索树(AVL树 插入)

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

二叉搜索树(AVL树 删除)

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

二叉搜索树(AVL树 3+4 重构)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
问题:视频里讲解的插入和删除算法可以用于AVL树的任何节点吗?(by wangyanhong11)
答:插入必然会插入到叶节点。因为如果在非叶节点就找到了的话,就会停止插入,报告“已存在”。

删除是可以应用到非叶节点的。删除操作会从删除节点开始,逐层网上检查是否平衡,遇到不平衡的就会进行局部调整,详见视频(by yuantailing 老师)
问题:
在这里插入图片描述
此处v,p,g应分别为17,19,23. 在v17这个子树中插入节点13,故根据重平衡算法,p(19)取代g(23)的地位,依序应为B。 请教一下这个环节是哪里考虑的有问题了呢?(by 小脚丫208688 )
答:v,p,g是13,17,19(by 不羁的逆袭)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值