浅谈平衡树

平衡树

算法简介

平衡树是一种支持

  1. 插入一个整数 x

  2. 删除一个整数x(若有多个相同的数,只删除一个)。

  3. 查询整数 x 的排名(排名定义为比当前数小的数的个数 +1)。

  4. 查询排名为 x 的数(如果不存在,则认为是排名小于 x 的最大数)。

  5. x 的前驱(前驱定义为小于 x,且最大的数)。

  6. x 的后继(后继定义为大于 x,且最小的数)。

等操作,并且支持在线的数据结构

分类

  1. 伪平衡树(并不是平衡树)
  2. Treap
  3. 替罪羊树
  4. AVL树
  5. 伸展树
  6. 红黑树
  7. 加权平衡树
  8. 2-3树
  9. AA树
  10. 节点大小平衡树

伪平衡树

注意:这并不是平衡树,只是可以支持大部分平衡树的操作的一种结构

实质:vector + lower_bound

vector

vector 是一种支持任意位置插入、删除和查询的一个结构。

定义方法std::vector<int>vec;//其中int可改为任意结构

它有以下几个常用函数:

  1. push_back(x)在尾部加入一个元素 x
  2. insert(pos,x) 在 pos 位置插入一个元素 x
  3. pop_back()在尾部删除一个元素
  4. erase(pos)在 pos 位置删除一个元素
  5. begin()返回第一个元素的位置
  6. end()返回最后一个元素的位置
  7. “operator[x]” 返回第 x 个元素
lower_bound

lower_bound 是 stl 自带的二分查找函数。

用法:std::lower_bound(/*起始地址*/,/*结束地址*/,/*所查询元素*/)

它会返回第一个小于等于所查询元素的位置。

实现
#include<bits/stdc++.h>
using namespace std;
int N,opt,x;
vector<int>vec;
int main(){
   
	scanf("%d",&N);
	while(N--){
   
		scanf("%d%d",&opt,&x);
		if(opt==1){
   vec.insert(lower_bound(vec.begin(),vec.end(),x),x);}
		if(opt==2){
   vec.erase(lower_bound(vec.begin(),vec.end(),x));}
		if(opt==3){
   printf("%d\n",lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1);}
		if(opt==4){
   printf("%d\n",vec[x-1]);}
		if(opt==5){
   printf("%d\n",vec[lower_bound(vec.begin(),vec.end(),x)-vec.begin()-1]);}
		if(opt==6){
   printf("%d\n",*lower_bound(vec.begin(),vec.end(),x+1));}
	}
} 
优缺点

优点:代码简短,不易打挂,易调试,支持在线。

缺点:由于 vector 和 lower_bound 的嵌套使用,时间复杂度较高。

适用于:

  1. 数据范围较小(一般 n ≤ 1 0 6 n\le10^6 n106 均可)

  2. 对常数要求不高的平衡树算法

Treap

Treap这个名字十分有内涵:

T r e e + H e a p = T r e + e a p = T r e a p \color{red}{Tree} \color{black}{+} \color{blue}{Heap} \color{black}{=} \color{red}{Tre} \color{black}{+} \color{blue}{eap} \color{black}{=} \color{red}{Tr}\color{purple}{e}\color{blue}{ap} Tree+Heap=Tre+eap=Treap

即 Treap = Tree(二叉搜索树) + Heap(堆)

这也是 Treap 能够平衡的关键。

基础操作
节点

对于每一个节点我们都会给它以下几个参数:

struct Treap{
   
    int l,//左儿子
    	r,//右儿子
    	val,//键值
    	ord,//随机值
    	siz,//子树大小
    	num;//同键值的数的个数
}t[Maxn];
旋转

旋转分为左旋(zig)和右旋(zag),如下图:

zig-zag

图1的中序遍历: D → B → E → A → C D\to B\to E\to A\to C

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值