912常考的几种树和堆

一、AVL树

1.每个结点的平衡因子的绝对值不超过1(某个节点x的平衡因子=左孩子高度-右孩子高度)

2.高度看的是这棵树中最深的那个节点,深度看的是这个节点的层次(规定根节点的那一层为第0层)

3.插入和删除的区别

失衡节点需要进行的操作进行操作后树的总高度是否变化进行一次调整后失衡会不会向上传播
插入可能有多个单旋或者双旋旋转后高度会恢复到未插入节点前不会
删除只会有1个,甚至没有单旋或者双旋恢复平衡后高度可能比删除节点的要小

4.重平衡根据g(x)找p,v节点时,都是优先选择高度更高的孩子或者和父亲同侧的孩子(这是俩孩子等高的情况下采取的措施)

5.删除节点时什么时候会导致树高比删除前的要小?
在这里插入图片描述
在这里插入图片描述
6.按递增次序将2h+1-1个关键码插入初始为空的AVL树中,必然得到高度为h的满树(习题7-20)。然后利用这个结论,结合二叉查找树左小右大的特点,可以很容易地证明下面这个题目的充分性;至于必要性,可以比较直观地看出来,如果不是满树,那两次构造的堆肯定不一样
在这里插入图片描述
至于具体的证明,请看大佬的github

二、伸展树(splay树,P205)

1)经前人证明,伸展树的单次操作均可在分摊的O(logn)时间内完成(证明过程你不要学,记住结论就行)

2)在伸展树中,如果,即便节点v的深度为Ω(n),双层伸展策略既可将v推至树根,还可以让对应分支的长度收缩到原来的一半

3)删除节点的算法思想:
在这里插入图片描述
主要是要记一下,删除节点后,新的伸展树的树根为TR中的最小关键码
概括一下,伸展树中一个节点的删除包括:一次查找+一轮伸展+一次摘除+又一次查找+又一轮伸展

4)插入节点的算法如下,这个就没什么好说的了,就是:一次查找+一轮伸展
在这里插入图片描述

5)AVL树中也有单旋和双旋,和splay树中的单层伸展和双层伸展有点类似,但是splay树是要把刚访问过的节点挪到树根,一次插入或者删除都需要多次伸展;而AVL树则是把不平衡性解决了就行,除了少数情况下的删除,其它大部分情况都只需要一次单旋或者一次双旋;从这里也可以看出来,AVL树关注的是平衡性,splay树关注的被访问的那个节点

6)伸展树和AVL树的比较:

编程难易程度分摊复杂度局部性
AVL需要记录结点高度和平衡因子,较为复杂两种树相同,都是O(logn)不适用于局部性很强的场合
splay不需要记录结点高度和平衡因子,相对简单两种树相同,都是O(logn)适用于局部性强的场合

其它方面的评价:
i)不能杜绝单次最坏情况出现,不适用于对效率敏感的场合
ii)复杂度的分析稍显复杂


三、B-树

1)对于m阶B树,相较于同等结点规模的BBST,最大树高会缩减到1/(log2m-1),最小树高会缩减到1/log2m。所以,对于256阶B树,至少可以缩减到原二分查找树的1/7,最多可以缩减到1/8

四、红黑树


五、左式堆(用于堆合并,P297)

1.最右侧通路和堆的最小规模的关系如果最右侧通路的长度为d,那么至少包含2d+1-1个节点(包括了外部节点),至少包含2d-1个内部节点

2.npl(null path length)和高度、深度之类的不一样,它的定义如下:
在这里插入图片描述
而左式堆中又要保证所有节点的npl(x->lchild)npl(x->rchild)
这样一来,npl(x)=1+npl(x->rchild),即左式堆中某个节点的npl只取决于其右孩子

3.左倾并不意味着左孩子的高度必大于等于右孩子的高度,左倾只能说明每个节点到达右孩子的空节点不比左孩子的空节点慢。如下面这个左式堆,就是右孩子高度大于左孩子高度:
在这里插入图片描述
所以,也说明左孩子的规模并不一定大于等于右孩子的规模,
即左孩子的高度和规模都可以小于右孩子。

4.每个节点的npl值,恰好等于其最右侧通路的长度

5.最右侧通路:从x出发沿右侧分支一直前行直至空节点,经过的通路称作其最右侧通路,记作rPath(x)

6.根节点的最右侧通路的终点必为全堆中深度最小的外部节点

7.合并:
在这里插入图片描述
结合实例更直观一点:
在这里插入图片描述

每次迭代开始时,都先判断两个堆中,谁要当谁的孩子,以及谁要移到左边,谁要移到右边:比如17要放在左边,15要放在右边,于是就把17的右孩子拿出来和以15为根的堆来进行合并成17的新右孩子;当合并全部完成后,还要从当前合并堆的父节点出发,考察它左右孩子的npl值,看是否需要调换左右孩子的顺序,比如上面这个实例中的d->e

8.借助左式堆进行堆合并的时间复杂度为O(max(logn,logm)),堆合并的算法如下,可以看到,通过第5行的swap,,确保右边的堆的根都是较小的那个:
在这里插入图片描述
9.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值