数据结构——Treap

简介

树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树。其基本操作的期望时间复杂度为O(logn)。相对于其他的平衡二叉搜索树,Treap的特点是实现简单,且能基本实现随机平衡的结构。

实现

节点结构

#define lc(x) t[x].lc
#define rc(x) t[x].rc
#define v(x) t[x].key
#define p(x) t[x].pri
#define c(x) t[x].cnt
#define s(x) t[x].sze
struct node{
    int lc;
    int rc;
    int key;
    int pri;
    int cnt;
    int sze;
}t[100010];
int pool,rt;

节点信息更新

void update(const int k){
    //update the treap 
    s(k)=s(lc(k))+s(rc(k))+c(k);
}

左旋

Zig

void zig(int &k){
    //left
    int y=lc(k);
    lc(k)=rc(y);
    rc(y)=k;
    s(y)=s(k);
    update(k);
    k=y;
}

右旋

Zag

void zag(int &k){
    //right
    int y=rc(k);
    rc(k)=lc(y);
    lc(y)=k;
    s(y)=s(k);
    update(k);
    k=y;
}

插入

void insert(int &k,const int key){
    //insert a node
    if(!k){
        k=++pool;
        v(k)=key;
        p(k)=rand();
        c(k)=s(k)=1;
        lc(k)=rc(k)=0;
        return;
    }
    s(k)++;
    if(v(k)==key) ++c(k);
    else if(key<v(k)){
        insert(lc(k),key);
        if(p(lc(k))<p(k)) zig(k);	//satisfy the nature of the heap
    }else{
        insert(rc(k),key);
        if(p(rc(k))<p(k)) zag(k);	//satisfy the nature of the heap
    }
}

删除

void remove(int &k,const int key){
	//delete a node
    if(v(k)==key){
        if(c(k)>1) --c(k),--s(k);
        else if(!lc(k)||!rc(k)) k=lc(k)+rc(k);
        else if(p(lc(k))<p(rc(k))) zig(k),remove(k,key);	//satisfy the nature of the heap
        else zag(k),remove(k,key);	//satisfy the nature of the heap
        return;
    }
    s(k)--;
    if(key<v(k)) remove(lc(k),key);
    else remove(rc(k),key);
}

查询前驱(不大于指定值的最大值)

int querypre(const int key){
	//lower
	int x=rt,res=-10000001;
	while(x){
		if(v(x)<key) res=v(x),x=rc(x);
		else x=lc(x);
	}
	return res;
}

查询后驱(不小于指定值的最小值)

int querynext(const int key){
	//upper
	int x=rt,res=-10000001;
	while(x){
		if(v(x)>key) res=v(x),x=lc(x);
		else x=rc(x);
	}
	return res;
}

查询第K大的值

int querykth(int k){
	int x=rt;
	while(x){
		if(s(lc(x))<k&&s(lc(x))+c(x)>=k) return v(x);
		if(s(lc(x))>=k) x=lc(x);
		else k-=s(lc(x))+c(x),x=rc(x);
	}
	return 0;
}

查询排名

int queryrank(const int key){
	int x=rt,res=0;
	while(x){
		if(key==v(x)) return res+s(lc(x))+1;
		if(key<v(x)) x=lc(x);
		else res+=s(lc(x))+c(x),x=rc(x);
	}
	return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值