Название:— смесьдереваикучи.указывает на то, что Treaps проявляют свойства как двоичных поисковых деревьев, так и кучи. Потолок - это двоичное дерево поиска, которое заказывает узлы по ключу, но также по атрибуту приоритета. Узлы упорядочены так, что ключи образуют двоичное дерево поиска, а приоритеты подчиняются свойству максимального кучного порядка.
Если у вас есть левый потомок, то ключ [v]< ключ [u];
Если же он является прямым потомком u, то ключ [v] >ключ [u];
Если v — ребенок u, то приоритет[v]<= приоритет[u];
Если приоритеты не случайны, дерево обычно несбалансировано; это худшее теоретическое среднестатистическое поведение может быть перевешено лучшим ожидаемым поведением, поскольку наиболее важные элементы будут близки к корню. Это означает, что наиболее важные объекты будут извлечены быстрее, чем менее важные предметы, и для элементов ключи с равными ключами будут найдены в первую очередь. Эти свойства важны для некоторых применений.
Сравнение приоритетов будет предоставляться так же, как и сравнение ключей, через объект функции, который будет храниться в навязчивом контейнере. Это означает, что приоритет может храниться в значении, которое должно быть введено в кран или вычислено в полете (через хеширование или подобное).
Boost.Intrusiveпредлагает 3 контейнера на основе кранов:<treap_set>,<treap_multiset>и<treap>. Первые два похожи на<set>или<multiset>, а последний представляет собой обобщение, которое предлагает функции как для вставки уникальных, так и нескольких ключей.
Память над этими контейнерами с Boost. Навязчивые крючки - 3 указателя.
Пустое,<treap_set>,<treap_multiset>или<treap>имеет также размер 3 указателей и целое число (предполагая пустые функциональные объекты для сравнения ключа и приоритета и размера постоянного времени).
<base_hook<classHook>>/<member_hook<classT,classHook,HookT::*PtrToMember>>/<value_traits<classValueTraits>>: Чтобы указать тип крючка или характеристики значения, используемые для настройки контейнера. (Чтобы узнать о ценностных чертах, перейдите в разделКонтейнеры с пользовательскими ValueTraits.)
<constant_time_size<boolEnabled>>: Для активации операции постоянного времени<size()>. Дефолт:<constant_time_size<true>>
<size_type<boolEnabled>>: Указать тип, который будет использоваться для хранения размера контейнера. Дефолт:<size_type<std::size_t>>
Также они могут получить дополнительные опции:
<compare<classCompare>>: Функция сравнения для объектов, которые вставляются в контейнеры. Сравнительный функтор должен вызывать строгий слабый порядок. Дефолт:<compare<std::less<key_type>>>
<priority<classPriorityCompare>>: Функция сравнения приоритетов для объектов, вставляемых в контейнеры. Сравнительный функтор должен вызывать строгий слабый порядок. Дефолт:<priority<priority_compare<key_type>>>
<key_of_value<classKeyOfValueFunctionObject>>: Объект функции, который будет определять<key_type>типа значения, которое должно храниться. Этот тип позволит использовать картографический интерфейс.Карта и многокарточный интерфейс с множеством и множествомдля деталей. По умолчанию<key_type>равно<value_type>(набороподобный интерфейс).
Функция объекта по умолчанию<priority_compare<T>>будет называть неквалифицированную функцию<priority_order>, передавая две постоянные<T>ссылки в качестве аргументов, и должна вернуться истинной, если первый аргумент имеет более высокий приоритет (он будет искаться быстрее), вызывая строгий слабый порядок. Функция будет найдена с помощью поиска ADL, так что пользователю просто нужно определить функцию<priority_order>в том же пространстве имен, что и класс:
В целом, интрузивные контейнеры предлагают надежные гарантии безопасности, но контейнеры для погрузки должны иметь дело с двумя функторами (один для заказа стоимости, другой для приоритетного заказа). Кроме того, операции по стиранию помета требуют ротации на основе функции приоритетного порядка, и эта проблема ухудшает обычную гарантию отсутствия броска<erase(const_iterator)>. Тем не менее, инвазивное поведение предлагает самое сильное поведение в этих ситуациях. В резюме:
Если функтор приоритетного заказа не выбрасывает контейнеры на основе крана, предлагаются точно такие же гарантии, как и другие контейнеры на основе дерева.
Если в приоритетный заказ бросает функтор, контейнеры на основе крана предлагают сильную гарантию.
Теперь рассмотрим небольшой пример с использованием двоичных крючков деревьев поиска и контейнеров<treap_set>/<treap_multiset>:
#include<boost/intrusive/treap_set.hpp>#include<vector>#include<functional>#include<cassert>usingnamespaceboost::intrusive;classMyClass:publicbs_set_base_hook<>//This is a base hook{intint_;unsignedintprio_;public://This is a member hookbs_set_member_hook<>member_hook_;MyClass(inti,unsignedintprio):int_(i),prio_(prio){}unsignedintget_priority()const{returnthis->prio_;}//Less and greater operatorsfriendbooloperator<(constMyClass&a,constMyClass&b){returna.int_<b.int_;}friendbooloperator>(constMyClass&a,constMyClass&b){returna.int_>b.int_;}//Default priority comparefriendboolpriority_order(constMyClass&a,constMyClass&b){returna.prio_<b.prio_;}//Lower value means higher priority//Inverse priority comparefriendboolpriority_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 ordertypedeftreap_set<MyClass,compare<std::greater<MyClass>>>BaseSet;//Define an multiset using the member hook that will storetypedefmember_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 valuestd::vector<MyClass>values;for(inti=0;i<100;++i)values.push_back(MyClass(i,(i%10)));BaseSetbaseset;MemberMultisetmembermultiset;//Now insert them in the setsfor(VectItit(values.begin()),itend(values.end());it!=itend;++it){baseset.insert(*it);membermultiset.insert(*it);}//Now test treap_sets{BaseSet::reverse_iteratorrbit(baseset.rbegin());MemberMultiset::iteratormit(membermultiset.begin());VectItit(values.begin()),itend(values.end());//Test the objects inserted in the base hook treap_setfor(;it!=itend;++it,++rbit)if(&*rbit!=&*it)return1;//Test the objects inserted in the member hook treap_setfor(it=values.begin();it!=itend;++it,++mit)if(&*mit!=&*it)return1;//Test priority orderfor(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;}
Статья Intrusive treap based associative containers: treap_set, treap_multiset and treap раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 17. Boost.Intrusive может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.