Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体。BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添加一个优先级属性,值的大小随机生成,用最大堆的方式维护。之所以使用堆,是因为堆是一颗 完全二叉树,而BST梦寐以求的就是完全二叉结构,二者一结合,就产生了一种新的Balanced BST。Treap依赖于随机数,随机生成的优先级属性,通过简单的左右旋可以将长链旋转成近似完全二叉树结构,注意只是近似,平均情况下的树高是(log 1.46n),但是完全二叉是(log 2n),可以说还是有一点点差距的,不过基本接近红黑树的平衡状况。鉴于比红黑树好拍,而且可塑性很强(如果你是用STL红黑树),在不是很追求鲁棒性的前提下,Treap算是神器了。
常规的BST用不着Treap,Treap的一大作用是求第K大数,具体方法是每个结点维护一个附加信息s,s为所有子结点和自身结点的数量,形成一颗 Rank Tree(名次树),如果你是手拍红黑树,可以自己实现,用不着Treap。但是如果使用STL,STL高度封装特性使得我们无法定制自己的树,这点着实 蛋疼。记住Treap的优势:简化的可定制的红黑树!
先来介绍一下Treap的结点结构。
struct node { node *ch[2]; int v,r,s; //v-value,r-random值,s-附加结点信息 int cmp(int x) { if(x==v) return -1; return x<v?0:1; //0-left,1-right } void maintain() //维护附加信息s { s=1; if(ch[0]!=NULL) s+=ch[0]->s; if(ch[1]!=NULL) s+=ch[1]->s; } }