数据结构——树

 

1.AVL树(自平衡二叉查找树)

1)插入

avl树的插入操作每次可能会导致多个祖先失衡,但是它只要修改一次(最低的那个祖先节点),更高的祖先的高度也会复原。

解决办法:单旋,复杂度为O(1);双旋(对应于”之“字形的情况)(实际并非简单地如此操作)(O(logn))

具体实现:

 

2)删除

avl树的删除操作每次只可能导致一个祖先失衡(因为若删除一个节点导致失衡,则该节点一定在较矮的子树上,而计算树的高度时是由较高的子树决定的,故与它无关),但它改了这一个节点,可能又会引发其他节点的失衡,故相对于插入,删除操作更复杂。

解决办法:单旋(可能会达到O(logn))、双旋(可能达到O(logn))(实际并非如此简单地操作)

具体实现:

注意,起点为被删除节点的父亲。

 

3)3+4重构

把根节点及其以下两个节点重命名为a,b,c,把其下四棵子树重命名为t1,t2,t3,t4,按照中序遍历的方式,可得到t1->a->t2->b->t3->c->t4的结构。即BTS的单调性。无论如何调整,最终我们都要调整为如此结构。

 

具体实现:

 

关键——如何按照规则重命名:找出是左旋/右旋/左右旋/右左旋中的哪种情况,然后根据中序遍历的顺序确定重命名的节点位置。

 

4)总结

优点:查找、插入、删除等操作的最坏情况复杂度均为O(logn)。空间复杂度为O(n)。

缺点:借助高度或平衡因子,为此需改造元素结构,或额外封装;实测复杂度与理论值尚有差距;旋转花销大;单次动态调整后,全树的拓扑结构的变化量可能达到O(logn)(删除操作)。

 

2.伸展树

根据数据的局部性特点,通过伸展将节点v调整到树根的操作。

局部性:刚被访问过的数据,极有可能很快地再次访问

伸展:通过将节点v进行若干次旋转,最终移动到树根的过程。伸展采用的是Tajan的双层伸展方法,即先对v的祖父进行一次zig/zag操作,再对v的父亲节点进行zig/zag操作,从而使v到达祖父的位置。

好处:对于坏节点(e.g 只有左子树的二叉树的最后一个节点)的访问,每一次伸展都会将树高降低一半。分摊下去整个调整过程的每次调整时间复杂度为O(logn)。

 

1)具体实现

 

伸展树接口

与AVL的差别:AVL不用重写search()函数。

 

伸展功能

 

判断左/右孩子而进行相应操作的函数:它的具体变换过程与3+4重构很类似,不再赘述,这里采用拼接的函数形式略过。

           

 

 

搜索功能

伸展树区别于其他BST的本质特点:它的search()操作不是静态操作。其内部调用了splay()函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值