zoukankan      html  css  js  c++  java
  • Treap实现山寨set

    treap插入、删除、查询时间复杂度均为O(logn)

    treap树中每个节点有两种权值:键值和该节点优先值

    如果只看优先值,这棵树又是一个堆

    treap有两种平衡方法:左旋&右旋

    insert 插入

    remove 删除

    _find 查找

    kth 返回root为根的树中第k大的元素

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <ctime>
      5 #include <cstdio>
      6 using namespace std;
      7 
      8 struct Node
      9 {
     10     Node* ch[2];
     11     int r,v,s;    //r:随机优先级,v:值,s:以本节点为根的子树的结点总数
     12     bool operator < (const Node& rhs)
     13     {
     14         return (r<rhs.r);
     15     }
     16     int cmp(int x)
     17     {
     18         if (x==v) return -1;
     19         return x<v?0:1;
     20     }
     21     void maintain()
     22     {
     23         s=1;
     24         if (ch[0]!=NULL) s+=ch[0]->s;
     25         if (ch[1]!=NULL) s+=ch[1]->s;
     26     }
     27     Node (int v):v(v)        //结构体的构造函数
     28     {
     29         ch[0]=ch[1]=NULL;
     30         r=rand();
     31         s=1;
     32     }
     33 };
     34 
     35 void rotate(Node* &o,int d)
     36 {
     37     Node* k=o->ch[d^1];
     38     o->ch[d^1]=k->ch[d];
     39     k->ch[d]=o;
     40     o->maintain();
     41     k->maintain();
     42     o=k;
     43 }
     44 
     45 void insert(Node* &o,int x)
     46 {
     47     if (o==NULL)
     48         o=new Node(x);
     49     else
     50     {
     51         //int d=o->cmp(x);        //不用cmp
     52         int d=(x < o->v ? 0 : 1);
     53         insert(o->ch[d],x);
     54         if (o->ch[d]->r > o->r)
     55             rotate(o,d^1);
     56     }
     57     o->maintain();
     58 }
     59 
     60 void remove(Node* &o,int x)
     61 {
     62     int d=o->cmp(x);
     63     if (d==-1)
     64     {
     65         Node *u=o;
     66         if ((o->ch[0]!=NULL) && (o->ch[1]!=NULL))
     67         {
     68             int d2=(o->ch[0]->r > o->ch[1]->r ? 1 : 0);
     69             rotate(o,d2);
     70             remove(o->ch[d2],x);
     71         }
     72         else
     73         {
     74             if (o->ch[0]==NULL)
     75                 o=o->ch[1];
     76             else
     77                 o=o->ch[0];
     78             delete u;
     79         }
     80     }
     81     else
     82         remove(o->ch[d],x);
     83     if (o!=NULL)
     84         o->maintain();
     85 }
     86 
     87 int kth(Node* o,int k)
     88 {
     89     if ((o==NULL)||(k<=0)||(k > o->s))
     90         return 0;
     91     int s=(o->ch[1]==NULL ? 0 : o->ch[1]->s);
     92     if (k==s+1)
     93         return o->v;
     94     else if (k<=s)
     95         return kth(o->ch[1],k);
     96     else
     97         return kth(o->ch[0],k-s-1);
     98 
     99 }
    100 
    101 int _find(Node* o,int x)
    102 {
    103     while (o!=NULL)
    104     {
    105         int d=o->cmp(x);
    106         if (d==-1)
    107             return 1;
    108         else
    109             o=o->ch[d];
    110     }
    111     return 0;
    112 }
    113 
    114 int main()
    115 {
    116     //freopen("in.txt","r",stdin);
    117 
    118     int n,m,opr,x;
    119     srand(time(0));
    120     cin>>n;
    121     Node* root=new Node(0);
    122     for (int i=1;i<=n;i++)
    123     {
    124         cin>>opr>>x;
    125         if (opr==1)
    126         {
    127             insert(root,x);
    128         }
    129         else if (opr==2)
    130         {
    131             if (!_find(root,x))
    132                 cout<<"Not Found,Operation Failed"<<endl;
    133             else
    134                 remove(root,x);
    135         }
    136     }
    137     cout<<"-----------------"<<endl;
    138     cin>>m;
    139     for (int i=1;i<=m;i++)
    140     {
    141         cin>>x;
    142         if (_find(root,x))
    143             cout<<"Found"<<endl;
    144         else
    145             cout<<"Not Found"<<endl;
    146     }
    147     cout<<"-----------------"<<endl;
    148     cin>>m;
    149     for (int i=1;i<=m;i++)
    150     {
    151         cin>>x;
    152         int ans=kth(root,x);
    153         cout<<x<<"th: "<<ans<<endl;
    154     }
    155 }
    View Code

    PS:发现一个画图论图形的神器:GraphViz

  • 相关阅读:
    爬虫时http错误提示
    json.dumps()和json.loads()
    scrapy框架原理学习
    利用tushare进行对兴业银行股价的爬取,并使用numpy进行分析
    随机生成60位同学成绩,并求他们的平均数,中位数,众数等
    numpy中random的使用
    matplotlib中subplot的使用
    使用matplotlib画饼图
    乔坟,乔坟!
    c#控件的动画显示效果
  • 原文地址:https://www.cnblogs.com/pdev/p/4027631.html
Copyright © 2011-2022 走看看