替罪羊树详解

替罪羊树详解

刚开始学习平衡树。可是我太弱了弄不懂有旋转操作的treap和splay,这时候学习可以不用旋转操作——替罪羊树的平衡树就很适合。这个名字取得比较玄乎,一眼看上去并不知道有什么卵用,但是, 如果你是刚学平衡树的新手,那么从替罪羊树开始学一定是个绝佳的选择,因为它是个很优雅的平衡树,什么叫优雅?暴力即是优雅!

如果在一棵平衡的二叉搜索树内进行查询等操作,时间就可以稳定在log(n),但是每一次的插入节点和删除节点,都可能会使得这棵树不平衡,最坏情况就是退化成一条链,显然我们不想要这种树,于是各种维护的方法出现了,大部分的平衡树都是通过旋转来维护平衡的,但替罪羊树就很厉害了,一旦发现不平衡的子树,立马拍扁重建,这就是替罪羊树的核心:暴力重建

先来说说我的替罪羊树上的每个节点包含些什么:

(1) zuo,you:记录该节点的左右儿子

(2)x:该节点的值

(3)tot:有多少个值为x的数

(4) size,trsize,whsize:size表示以该节点为根的子树内有多少个节点,trsize表示有多少个有效节点(这个后面再讲啦),whsize表示有多少个数(也就是子树内所有节点的tot的和)

(5)fa:该点的父亲

(6)tf:该点是否有删除标记(这个也会在后面讲啦)

用处

替罪羊树是一种平衡树,支持插入,删除,查找第k小元素,查找元素的排名等操作

1、关于α

在替罪羊树中,定义了一个平衡因子α,α的范围因题而异,一般取0.5~1.0之间,若题目没有特殊说明,一般就取个中0.75就好了。那这个α有啥用呢?替罪羊树判断一棵子树是否平衡的方法是:如果 x的左(右)子树的节点数量 > 以x为根的子树的节点数量α ,那么,以x为根的这棵子树就是不平衡的。显然的,如果有一棵子树的大小超过了 以x为根的子树的节点数量α,那么这种节点一边倒的情况对于查询来说肯定就很慢,所以,这个时候我们就将它重建。
不知各位有木有想过,α的值究竟与效率有什么关系呢?仔细想想,当α的值越小,那么替罪羊树就越容易重构,那么树也就越平衡,查询的效率也就越高,自然修改(加点和删点)的效率也就低了,所以,如果查询操作比较多的话,就可以将α的值设小一点,反之,假如修改操作多,自然α的值就要大一点了。

还有,α不能等于1 or 0.5,假如它等于0.5,那么当一棵树被重构之后如果因为节点数问题,不能完全重构成一个完全二叉树,那么显然,对于这棵树的根,他的 | 左子树节点数量 - 右子树节点数量 | 很可能会等于1,那么如果往多的那棵子树上加一个节点,那么这棵树又得重构一次,最坏情况时间会变成n^2,显然死定了。。那么等于1会怎么样?还能怎么样!你觉得会有一棵子树的大小大于整棵树的大小吗?!

2、关于时间复杂度

除了重构操作,其他操作的时间复杂度显然都是log(n)的,那么下面看一下重构的时间复杂度。

虽然重构一次的时间复杂度是O(n)的,但是,均摊下来其实只是O(logn)。

考虑极端情况,每次都把整棵树重构。

那么我们就需要每次都往根的一棵子树内加点,假设一开始是平衡的,那么左右子树各有50%的节点,那么要使一棵子树内含有超过75%的节点,那么这棵子树就需要在原来的基础上增加2倍的节点数。也就是说,当最差情况时,整棵替罪羊树的节点数要翻个倍,才会重构。那么最差情况时也就是在4,8,16,32……个节点时才会重构,于是重构的总的时间复杂度也就是O(nlogn)了,加上一些杂七杂八的重构,也不过就是加上一个很小的常数,可以省略不计。所以,替罪羊树的时间复杂度依然是O(nlogn)的。
引用博客:一、结构体指针
二、树状数组
三、带图更清晰

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值