Treap-非指针总结

【Treap】

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

【操作】
注:

struct Treap
{
    int x,l,r,w,s,ran;//x表示这个节点的权值,l表示这个节点的左儿子,r表示这个节点的右儿子,w表示该权值的数的个数,s表示这个节点的子树的的节点的w的总和,ran表示随机的权值。
}a[maxn];

void Updata(int k)
{
    a[k].s=a[a[k].l].s+a[a[k].r].s+a[k].w;
}

本人维护的是小根堆。(也可以维护大根堆)
本人目前不会指针。

① 右旋:
这里写图片描述

void Rturn(int &k)
{
    int t=a[k].l; a[k].l=a[t].r; a[t].r=k;
    a[t].s=a[k].s; Updata(k); k=t;
}

② 左旋:
这里写图片描述

void Lturn(int &k)
{
    int t=a[k].r; a[k].r=a[t].l; a[t].l=k;
    a[t].s=a[k].s; Updata(k); k=t;
}

③ 插入x数:

void Insert(int &k,int x)
{
    if (k==0) {k=++tot; a[k].x=x; a[k].w=a[k].s=1; a[k].ran=rand(); return;}
    a[k].s++;
    if (a[k].x==x) a[k].w++;
     else if (x<a[k].x)
      {
        Insert(a[k].l,x);
        if (a[a[k].l].ran<a[k].ran) Rturn(k);
      }
      else
       {
        Insert(a[k].r,x);
        if (a[a[k].r].ran<a[k].ran) Lturn(k);
       }
}

④ 删除x数:

void Delete(int &k,int x)
{
    if (k==0) return;
    if (a[k].x==x)
     {
        if (a[k].w>1) {a[k].w--; a[k].s--; return;}
         else if (!a[k].l||!a[k].r) k=a[k].l+a[k].r;
          else if (a[a[k].l].ran<a[a[k].r].ran) {Rturn(k); Delete(k,x);} else {Lturn(k); Delete(k,x);}//将节点旋转到叶子节点才能删除。
     }
     else if (x<a[k].x) a[k].s--,Delete(a[k].l,x); else a[k].s--,Delete(a[k].r,x);
}

⑤ 查询x数的排名:

int Rank(int k,int x)
{
    if (k==0) return 0;
    if (x==a[k].x) return a[a[k].l].s+1;
    if (x<a[k].x) return Rank(a[k].l,x); else return a[a[k].l].s+a[k].w+Rank(a[k].r,x);
}

⑥ 查询排名为x的数:

int Num(int k,int x)
{
    if (k==0) return 0;
    if (x<=a[a[k].l].s) return Num(a[k].l,x);
     else if (x>a[a[k].l].s+a[k].w) return Num(a[k].r,x-a[a[k].l].s-a[k].w);
      else return a[k].x;
}

⑦ 求x的前驱:

void Pre(int k,int x)
{
    if (k==0) return;
    if (x>a[k].x) {ans=a[k].x; Pre(a[k].r,x);} else Pre(a[k].l,x);
}

⑧ 求x的后继:

void Sub(int k,int x)
{
    if (k==0) return;
    if (x<a[k].x) {ans=a[k].x; Sub(a[k].l,x);} else Sub(a[k].r,x);
}

【例题】
bzoj3224

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是Treap的代码: ``` #include <bits/stdc++.h> using namespace std; struct Node { int key, priority; Node *left, *right; Node(int key, int priority) : key(key), priority(priority), left(NULL), right(NULL) {} }; struct Treap { Node *root; Treap() : root(NULL) {} void rotateRight(Node *&p) { Node *q = p->left; p->left = q->right; q->right = p; p = q; } void rotateLeft(Node *&p) { Node *q = p->right; p->right = q->left; q->left = p; p = q; } void insert(Node *&p, int key, int priority) { if (p == NULL) { p = new Node(key, priority); return; } if (key < p->key) { insert(p->left, key, priority); if (p->priority < p->left->priority) { rotateRight(p); } } else { insert(p->right, key, priority); if (p->priority < p->right->priority) { rotateLeft(p); } } } void remove(Node *&p, int key) { if (p == NULL) { return; } if (key == p->key) { if (p->left == NULL || p->right == NULL) { Node *q = p; if (p->left == NULL) { p = p->right; } else { p = p->left; } delete q; } else { if (p->left->priority > p->right->priority) { rotateRight(p); remove(p->right, key); } else { rotateLeft(p); remove(p->left, key); } } } else if (key < p->key) { remove(p->left, key); } else { remove(p->right, key); } } bool search(Node *p, int key) { if (p == NULL) { return false; } if (key == p->key) { return true; } if (key < p->key) { return search(p->left, key); } else { return search(p->right, key); } } }; int main() { Treap t; t.insert(t.root, 5, rand()); t.insert(t.root, 3, rand()); t.insert(t.root, 8, rand()); t.insert(t.root, 1, rand()); t.insert(t.root, 4, rand()); t.insert(t.root, 6, rand()); t.insert(t.root, 9, rand());

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值