李晓亮的博客

导航

【转】随机二叉搜索树 Treap

(当个日记记录Treap这一结构,详细参见http://www.nocow.cn/index.php/Treap, 在这里我着重讲一下旋转)

    Treap,它其它就是一个二叉查找树(BST)+堆(HEAP). 它的数据有两个:关键值(key),优先级(fix).

    用struct表示Treap的结点的结构如下:

   struct node

   {

        datatype key;

         int  fix;

         node * left;

         node * right;

  }

   Treap的key值满足BST的性质:即任一个Treap的结点x,若y是x的左子树,则y.key<=x.key,若y为x的右子树,则y.key>=x.key.

   同时Treap的fix满足Heap的性质(在这里以最大堆为例):即任一个Treap的结点x,若y为x的左子树或右子树,则x.fix>=y.fix.

   如下图所示则为Treap

 


      
Treap的作用:它的作用同BST一样,引入优先级这一概念是为了防止BST退化成一链表(BST的建立依籁于结点的插入顺序,当有序的插入时,则BST为一链表,其它查找插入的复杂度o(n)),当然我们完全可以随机的插入结点,但是有时候我们事先并不知道所有结点,在这种情况下我们可以采用Treap,即当需要插入的一个新的key值,我们可以随机的生成一个优先级(fix),然后通过fix约束Treap,从而达到随机生成BST的目的.

       为了插入和删除之后仍然保持Treap的两个性质,在这里Treap提供了两种旋转的操作,右旋和左旋

        (1)结点右旋:node x,y=x->left; 先将y的右子树作为x的左子树,然后将x作为y的右子树, 最后将y作为x原父结点的子树(x为左子树,此时y仍然为左子树,x为右子树,y也为右子树)如下图所示.

        

        

(2)结点左旋:同右旋刚好相反.node x,y=x->right; 先将y的左子树作为x的右子树,然后将x作为y的左子树, 最后将y作为x原父结点的子树(x为左子树,此时y仍然为左子树,x为右子树,y也为右子树)如下图所示.

      

    

由上可见,旋转操作之后仍然满足BST的特性,但是改变Heap的性质.

           插入操作:有了旋转操作后,插入变得十分简单.它只需要将结点(key,fix)BST插入到Treap,此时若不满足Heap的性质,若结点x的左子树的fix大于xfix,则只需要左旋,若结点y的右子树的fix值大于xfix,则左旋.直至满足Heap的性质.

          删除操作:只需要将删除的结点旋转至叶结点,直接插除即可.

          对于其它的查找,后继,最小值等操作均同BST一样,在这里便不再详述.附有C++ Treap实现.

         

  1. using std::ostream;   
  2. using std::endl;   
  3. using std::cout;   
  4.   
  5. class Treap   
  6. {   
  7.        
  8.     private:   
  9.         struct node   
  10.         {   
  11.             int key;   
  12.             int fix;//priority,for heap   
  13.             node * left,*right;//left child and right child   
  14.             node(const int &_k):key(_k),left(NULL),right(NULL),fix(rand())   
  15.             {   
  16.                    
  17.                    
  18.             }   
  19.                
  20.         };   
  21.         friend std::ostream & operator <<(std::ostream &os,node * const &r)   
  22.         {   
  23.             if(r==NULL)   
  24.                 return os;   
  25.             os<<r->left;   
  26.             os<<r->key<<std::endl;   
  27.             os<<r->right;   
  28.             return os;   
  29.         }   
  30.   
  31.         inline void rol_l(node * &x)//rotate to left on node x   
  32.         {   
  33.             node * y=x->right;   
  34.             x->right=y->left;   
  35.             y->left=x;   
  36.             x=y;   
  37.         }   
  38.         inline void rol_r(node * &x)//rotate to right on node x   
  39.         {   
  40.             node * y=x->left;   
  41.             x->left=y->right;   
  42.             y->right=x;   
  43.             x=y;   
  44.         }   
  45.         void insert(node * & r,const int &key)   
  46.         {   
  47.             if(r==NULL)   
  48.             {   
  49.                 r=new node(key);   
  50.             }else  
  51.             {   
  52.                 if(key<r->key)   
  53.                 {   
  54.                     insert(r->left,key);   
  55.                     if(r->left->fix>r->fix)   
  56.                         rol_r(r);   
  57.                 }else  
  58.                 {   
  59.                     insert(r->right,key);   
  60.                     if(r->right->fix>r->fix)   
  61.                         rol_l(r);   
  62.                 }   
  63.             }   
  64.   
  65.         }   
  66.         void remove(node * &r,const int &key)   
  67.         {   
  68.             if(r==NULL)   
  69.                 return;   
  70.             if(key<r->key)   
  71.                 remove(r->left,key);   
  72.             else if(key>r->key)   
  73.               remove(r->right,key);   
  74.             else  
  75.             {   
  76.                 //remove node r   
  77.                 if(r->left==NULL && r->right==NULL)   
  78.                 {   
  79.                     delete r;   
  80.                     r=NULL;   
  81.                 }else if(r->left==NULL)   
  82.                 {   
  83.                     node * t=r;   
  84.                     r=r->right;   
  85.                     delete r;   
  86.                 }else if(r->right==NULL)   
  87.                 {   
  88.                     node * t=r;   
  89.                     r=r->left;   
  90.                     delete t;   
  91.                 }else  
  92.                 {   
  93.                     if(r->left->fix<r->right->fix)   
  94.                     {   
  95.                         rol_l(r);   
  96.                         remove(r->left,key);   
  97.                     }else  
  98.                     {   
  99.                         rol_r(r);   
  100.                         remove(r->right,key);   
  101.                     }   
  102.                 }   
  103.   
  104.   
  105.   
  106.             }   
  107.         }   
  108.   
  109.         bool find(node * const & r,const int &key)   
  110.         {   
  111.             if(r==NULL)   
  112.                 return false;   
  113.             if(r->key==key)   
  114.                 return true;   
  115.             else  
  116.                 if(key<r->key)   
  117.                     return find(r->left,key);   
  118.                 else    
  119.                     return find(r->right,key);   
  120.   
  121.         }   
  122.   
  123.         void free(node * &r)   
  124.         {   
  125.             if(r==NULL)   
  126.                 return;   
  127.             free(r->left);   
  128.             free(r->right);   
  129.             delete r;   
  130.             r=NULL;   
  131.         }   
  132.         node * root;   
  133.     public:   
  134.         Treap():root(NULL)   
  135.         {   
  136.   
  137.         }   
  138.         ~Treap()   
  139.         {   
  140.             free(root);   
  141.         }   
  142.         void insert(const int &key)   
  143.         {   
  144.             insert(root,key);   
  145.         }   
  146.         void remove(const int &key)   
  147.         {   
  148.             remove(root,key);   
  149.   
  150.         }   
  151.            
  152.         bool find(const int &key)   
  153.         {   
  154.             find(root,key);   
  155.         }   
  156.   
  157.         friend std::ostream & operator <<(ostream & os,const Treap &t)   
  158.         {   
  159.             os<<t.root;   
  160.             return os;   
  161.   
  162.         }   
  163.            
  164.   
  165.   
  166.   
  167.   
  168. };   
  169.   
  170.   
  171. int main()   
  172. {   
  173.     Treap t;   
  174.     for(int i=0;i<10;i++)   
  175.      t.insert(i);   
  176.     std::cout<<t;   
  177.   
  178.     t.remove(3);   
  179.     cout<<"after remove 3"<<endl;   
  180.     std::cout<<t;   
  181.     t.remove(5);   
  182.     cout<<"after remove 5"<<endl;   
  183.     std::cout<<t;   
  184.   
  185.     system("pause");   
  186. }  

转自:http://blog.csdn.net/kuramawzw/archive/2009/08/07/4421315.aspx

posted on 2010-06-21 00:26  LeeXiaoLiang  阅读(439)  评论(0编辑  收藏  举报