Подобно красно-черным деревьям, деревья AVL являются сбалансированными двоичными деревьями. AVL-деревья часто сравнивают с красно-черными деревьями, потому что они поддерживают один и тот же набор операций и потому, что оба занимают время для основных операций. AVL-деревья более жестко сбалансированы, чем красно-черные деревья, что приводит к более медленной вставке и удалению, но более быстрому извлечению, поэтому AVL-деревья работают лучше, чем красно-черные деревья для приложений, требующих интенсивного поиска.
Навязчивыйпредлагает 3 контейнера на основе деревьев avl:<avl_set>,<avl_multiset>и<avltree>. Первые два похожи на<set>или<multiset>, а последний представляет собой обобщение, которое предлагает функции как для вставки уникальных, так и нескольких ключей.
Память над этими контейнерами с Boost. Навязчивые крючки обычно составляют 3 указателя и 2 бита (из-за выравнивания это обычно означает 3 указателя плюс целое число). Этот размер может быть уменьшен до 3 указателей, если указатели имеют выравнивание 4 байта (что обычно верно в 32-битных системах).
Размер пустого, непостоянного времени<avl_set>,<avl_multiset>или<avltree>также имеет размер 3 указателей и целое число (3 указателя при оптимизации для размера.
<tag<classTag>>(только для базовых крючков): Этот аргумент служит тегом, поэтому вы можете получить более одного базового крюка. Дефолт:<tag<default_tag>>.
<void_pointer<classVoidPointer>>: Тип указателя, который должен использоваться внутри крючка и распространяться на контейнер. Дефолт:<void_pointer<void*>>.
<optimize_size<boolEnable>>: Крючок будет оптимизирован под размер, а не скорость. Крюк будет встраивать балансовые биты узла дерева AVL в родительский указатель, если выравнивание указателя кратно 4. В некоторых платформах оптимизация размера может немного снизить производительность скорости, поскольку для доступа к атрибутам родительского указателя и фактора баланса потребуются операции маскировки, в других платформах эта опция повышает производительность благодаря улучшенной локализации памяти. Дефолт:<optimize_size<false>>.
<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>>>
<key_of_value<classKeyOfValueFunctionObject>>: Объект функции, который будет определять<key_type>типа значения для хранения. Этот тип позволит использовать картографический интерфейс.Карта и многокарточный интерфейс с множеством и множествомдля деталей. По умолчанию:<key_type>равно<value_type>(сет-подобный интерфейс).
Теперь рассмотрим небольшой пример с использованием как крючков, так и контейнеров<avl_set>/<avl_multiset>:
#include<boost/intrusive/avl_set.hpp>#include<vector>#include<functional>#include<cassert>usingnamespaceboost::intrusive;//This is a base hook optimized for sizeclassMyClass:publicavl_set_base_hook<optimize_size<true>>{intint_;public://This is a member hookavl_set_member_hook<>member_hook_;MyClass(inti):int_(i){}friendbooloperator<(constMyClass&a,constMyClass&b){returna.int_<b.int_;}friendbooloperator>(constMyClass&a,constMyClass&b){returna.int_>b.int_;}friendbooloperator==(constMyClass&a,constMyClass&b){returna.int_==b.int_;}};//Define an avl_set using the base hook that will store values in reverse ordertypedefavl_set<MyClass,compare<std::greater<MyClass>>>BaseSet;//Define an multiset using the member hooktypedefmember_hook<MyClass,avl_set_member_hook<>,&MyClass::member_hook_>MemberOption;typedefavl_multiset<MyClass,MemberOption>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));BaseSetbaseset;MemberMultisetmembermultiset;//Check that size optimization is activated in the base hookassert(sizeof(avl_set_base_hook<optimize_size<true>>)==3*sizeof(void*));//Check that size optimization is deactivated in the member hookassert(sizeof(avl_set_member_hook<>)>3*sizeof(void*));//Now insert them in the setsfor(VectItit(values.begin()),itend(values.end());it!=itend;++it){baseset.insert(*it);membermultiset.insert(*it);}//Now test avl_sets{BaseSet::reverse_iteratorrbit(baseset.rbegin());MemberMultiset::iteratormit(membermultiset.begin());VectItit(values.begin()),itend(values.end());//Test the objects inserted in the base hook avl_setfor(;it!=itend;++it,++rbit)if(&*rbit!=&*it)return1;//Test the objects inserted in the member hook avl_setfor(it=values.begin();it!=itend;++it,++mit)if(&*mit!=&*it)return1;}return0;}
Статья Intrusive avl tree based associative containers: avl_set, avl_multiset and avltree раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 17. Boost.Intrusive может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.