The name treap is a mixture of tree
and heap indicating that Treaps exhibit the properties
of both binary search trees and heaps. A treap is a binary search tree that
orders the nodes by a key but also by a priority attribute. The nodes are ordered
so that the keys form a binary search tree and the priorities obey the max
heap order property.

If v is a left descendant of u, then key[v] < key[u];

If v is a right descendant of u, then key[v] > key[u];

If v is a child of u, then priority[v] <= priority[u];

If priorities are non-random, the tree will usually be unbalanced; this worse
theoretical average-case behavior may be outweighed by better expected-case
behavior, as the most important items will be near the root. This means most
important objects will be retrieved faster than less important items and for
items keys with equal keys most important objects will be found first. These
properties are important for some applications.

The priority comparison will be provided just like the key comparison, via
a function object that will be stored in the intrusive container. This means
that the priority can be stored in the value to be introduced in the treap
or computed on flight (via hashing or similar).

Boost.Intrusive offers 3 containers based
on treaps: treap_set,
treap_multiset
and treap. The first two
are similar to set or multiset and the latter is a generalization
that offers functions both to insert unique and multiple keys.

The memory overhead of these containers with Boost.Intrusive hooks is 3 pointers.

An empty, treap_set,
treap_multiset
or treap has also the
size of 3 pointers and an integer (supposing empty function objects for key
and priority comparison and constant-time size).

treap_set, treap_multiset and treap don't use their own hooks
but plain binary search tree hooks. This has many advantages since binary
search tree hooks can also be used to insert values in splay containers and
scapegoat trees.

template<class...Options>classbs_set_base_hook;

bs_set_base_hook:
the user class derives publicly from this class to make it compatible with
scapegoat tree based containers.

template<class...Options>classbs_set_member_hook;

set_member_hook:
the user class contains a public member of this class to make it compatible
with scapegoat tree based containers.

base_hook<classHook>
/ member_hook<classT,classHook,HookT::*PtrToMember> / value_traits<classValueTraits>: To specify the hook type
or value traits used to configure the container. (To learn about value
traits go to the section Containers
with custom ValueTraits.)

size_type<boolEnabled>:
To specify the type that will be used to store the size of the container.
Default: size_type<std::size_t>

And they also can receive additional options:

compare<classCompare>:
Comparison function for the objects to be inserted in containers. The comparison
functor must induce a strict weak ordering. Default: compare<std::less<T>>

priority<classPriorityCompare>:
Priority Comparison function for the objects to be inserted in containers.
The comparison functor must induce a strict weak ordering. Default: priority<priority_compare<T>>

The default priority_compare<T>
object function will call an unqualified function priority_order
passing two constant T references
as arguments and should return true if the first argument has higher priority
(it will be searched faster), inducing strict weak ordering. The function
will be found using ADL lookup so that the user just needs to define a priority_order function in the same namespace
as his class:

In general, intrusive containers offer strong safety guarantees, but treap
containers must deal with two possibly throwing functors (one for value ordering,
another for priority ordering). Moreover, treap erasure operations require
rotations based on the priority order function and this issue degrades usual
erase(const_iterator)
no-throw guarantee. However, intrusive offers the strongest possible behaviour
in these situations. In summary:

If the priority order functor does not throw, treap-based containers, offer
exactly the same guarantees as other tree-based containers.

#include<boost/intrusive/treap_set.hpp>#include<vector>#include<algorithm>#include<cassert>usingnamespaceboost::intrusive;classMyClass:publicbs_set_base_hook<>//This is a base hook
{intint_;unsignedintprio_;public://This is a member hook
bs_set_member_hook<>member_hook_;MyClass(inti,unsignedintprio):int_(i),prio_(prio){}unsignedintget_priority()const{returnthis->prio_;}//Less and greater operators
friendbooloperator<(constMyClass&a,constMyClass&b){returna.int_<b.int_;}friendbooloperator>(constMyClass&a,constMyClass&b){returna.int_>b.int_;}//Default priority compare
friendboolpriority_order(constMyClass&a,constMyClass&b){returna.prio_<b.prio_;}//Lower value means higher priority
//Inverse priority compare
friendboolpriority_inverse_order(constMyClass&a,constMyClass&b){returna.prio_>b.prio_;}//Higher value means higher priority
};structinverse_priority{booloperator()(constMyClass&a,constMyClass&b)const{returnpriority_inverse_order(a,b);}};//Define an treap_set using the base hook that will store values in reverse order
typedeftreap_set<MyClass,compare<std::greater<MyClass>>>BaseSet;//Define an multiset using the member hook that will store
typedefmember_hook<MyClass,bs_set_member_hook<>,&MyClass::member_hook_>MemberOption;typedeftreap_multiset<MyClass,MemberOption,priority<inverse_priority>>MemberMultiset;intmain(){typedefstd::vector<MyClass>::iteratorVectIt;//Create several MyClass objects, each one with a different value
std::vector<MyClass>values;for(inti=0;i<100;++i)values.push_back(MyClass(i,(i%10)));BaseSetbaseset;MemberMultisetmembermultiset;//Now insert them in the sets
for(VectItit(values.begin()),itend(values.end());it!=itend;++it){baseset.insert(*it);membermultiset.insert(*it);}//Now test treap_sets
{BaseSet::reverse_iteratorrbit(baseset.rbegin()),rbitend(baseset.rend());MemberMultiset::iteratormit(membermultiset.begin()),mitend(membermultiset.end());VectItit(values.begin()),itend(values.end());//Test the objects inserted in the base hook treap_set
for(;it!=itend;++it,++rbit)if(&*rbit!=&*it)return1;//Test the objects inserted in the member hook treap_set
for(it=values.begin();it!=itend;++it,++mit)if(&*mit!=&*it)return1;//Test priority order
for(inti=0;i<100;++i){if(baseset.top()->get_priority()!=static_cast<unsignedint>(i/10))return1;if(membermultiset.top()->get_priority()!=9u-static_cast<unsignedint>(i/10))return1;baseset.erase(baseset.top());membermultiset.erase(membermultiset.top());}}return0;}