Почему станд :: Карта выполнена в виде красно-черного дерева ?
Есть несколько сбалансированные бинарные деревья поиска (BSTs) там. Какие конструктивные компромиссы в выборе красно-черного дерева?
Почему станд :: Карта выполнена в виде красно-черного дерева ?
Есть несколько сбалансированные бинарные деревья поиска (BSTs) там. Какие конструктивные компромиссы в выборе красно-черного дерева?
Вероятно , две наиболее распространенные алгоритмы дерева самобалансировани являются красно-черные деревья и AVL деревья . Для того, чтобы сбалансировать дерево после вставки / обновления оба алгоритма использует понятие вращений , где узлы дерева поворачиваются , чтобы выполнить повторную балансировку.
Хотя в обоих алгоритмов вставки / удаления операции O (Log га), в случае красно-черного дерева повторно балансировки вращения является O (1) операции , а с AVL это O (журнал п) операции, в результате чего Красно-черное дерево более эффективное в этом аспекте повторного балансирования стадии и одна из возможных причин того, что он чаще используется.
Красно-черные деревья используются в большинстве библиотек коллекции, в том числе предложения от Java и Microsoft .NET Framework.
Это только выбор вашей реализации - они могут быть реализованы в виде любого сбалансированного дерева. Различные варианты несравнимы с небольшими различиями. Поэтому любая столь же хорошо, как любой.
AVL деревья имеют максимальную высоту 1.44logn, а РБ деревья имеют максимум 2logn. Вставка элемента в AVL может означать восстановить баланс в одной точке в дереве. Перебалансирование заканчивает вставку. После вставки нового листа, обновление предков этого листа должно быть сделано до корня, или до момента, когда два поддерева имеют одинаковую глубину. Вероятность того, чтобы обновить узлы K 1 / ^ 3 к. Перебалансирование представляет собой О (1). Удаление элемента может подразумевать более одного перебалансирования (до половины глубины дерева).
RB-деревья B-деревья порядка 4 представлены в виде бинарных деревьев поиска. 4-узла в результатах B-деревьев в двух уровнях в эквивалентной BST. В худшем случае, все узлы дерева являются 2-узлами, с только одна цепью из 3-узлов вниз к листу. Этот лист будет на расстоянии 2logn от корня.
Спускаясь от корня до точки вставки, необходимо изменить 4-узлов в 2-х узлов, чтобы убедиться, что любая вставка не насытит лист. Возвращаясь из введения, все эти узлы должны быть проанализированы, чтобы убедиться, что они правильно представляют собой 4-узлы. Это также может быть сделано спускаясь в дереве. Глобальная стоимость будет такой же. Там нет бесплатного обеда! Удаление элемента из дерева имеет тот же порядок.
Все эти деревья требуют, чтобы узлы несут информацию по высоте, вес, цвет и т.д. Только Расширяющиеся деревья свободны от такой дополнительной информации. Но большинство людей боятся Splay деревьев, из-за ramdomness их структуры!
И, наконец, деревья могут также нести информацию о весе в узлах, что позволяет весовую балансировку. Различные схемы могут быть применены. Следует восстановить равновесие, когда поддерево содержит более чем в 3 раза больше элементов другого поддерева. Ребалансирование снова делается либо throuh одинарного или двойного поворота. Это означает худший случай 2.4logn. Можно сойти с рук 2 раза вместо 3, гораздо лучше соотношение, но это может означать, оставив немного меньше Тана 1% поддеревьев несбалансированное здесь и там. Tricky!
Какой тип дерева лучше? AVL точно. Они являются самыми простыми в коде, и имеют наихудший высоту возле LOGN. Для дерева элементов 1000000, АВЛ будет на большей части высоты 29, 40 в РБ, а вес уравновешивается 36 или 50 в зависимости от соотношения.
Есть много других переменных: хаотичность, отношение добавляет, удаляет, поиск и т.д.
Это действительно зависит от использования. AVL дерево обычно имеет больше поворотов перебалансирования. Так что, если ваше приложение не слишком много вставки и удаления операций, но веса в большой степени на поиске, то AVL дерево, вероятно, является хорошим выбором.
std::map использует красно-черное дерево, как он получает разумный компромисс между скоростью узлом вставкой / удалением и поиском.
Обновление 2017-06-14: webbertiger редактировать свой ответ после того, как я. Я должен отметить, что его ответ теперь намного лучше моих глазах. Но я продолжал свой ответ только в качестве дополнительной информации ...
В связи с тем, что я думаю, что первый ответ неверно (исправление: не так больше), а третьи имеют неправильное утверждение. Я чувствую, что я должен был прояснить вещи ...
2 самых популярных деревьев являются AVL и Red Black (РБ). Основное различие лежит в использовании:
Основное отличие исходить от окраски. Вы меньше действий повторно баланса в РБ, чем дерево AVL, потому что окраска позволяют иногда пропустить или сократить повторное балансовые действия, которые имеют относительную привет стоимость. Из-за окраски, RB дерева также имеют более высокий уровень узлов, так как он может принимать красные узлы между черными (имеющие возможности ~ более 2х уровней), что делает поиск (чтение) немного менее эффективной ... но потому, что это константа (2x), то оставаться в O (журнал N).
Если рассматривать падение производительности для модификации дерева (смысловой) VS хит производительности консультаций дерева (почти ничтожного), это стало естественным предпочитать RB над AVL для общего случая.
Предыдущие ответы только адрес альтернативу дерева и красные черный, вероятно, остается только по историческим причинам.
Почему бы не хэш-таблицы?
В дереве типа требуется лишь частичное упорядочение (<сравнение), который будет использоваться в качестве ключа в карте. Однако, хэш-таблицы требуют, чтобы каждый тип ключа имеет хэш-функцию, определенную. Соблюдение этих требований типа к минимуму очень важно для общего программирования.
Проектирование хорошей хеш-таблицы требует глубоких знаний в контексте которой она будет использоваться. Должен ли он использовать открытую адресацию, или связанные цепочки? Какой уровень нагрузки он должен принять перед изменением размеров? Должен ли он использовать дорогостоящий хэш, который позволяет избежать столкновения, или тот, который грубо и быстро?
(C ++ 11 сделала добавить хэш - таблицу с unordered_map. Вы можете видеть из документации , что требует настройку политики для настройки многих из этих опций.)
Поскольку STL не может предвидеть, что является лучшим выбором для вашего приложения, по умолчанию должно быть более гибкими. Деревья «просто работать» и масштабировать красиво.
А как насчет других деревьев?
Предложение быстрого поиска Red Black дерева и самостоятельной балансировки в отличие от BSTs. Другой пользователь указал свои преимущества перед самобалансирующимся AVL дерева.
Александр Степанов (Создатель STL) говорит , что он будет использовать B * Tree вместо красно-черного дерева , если он написал std::mapеще раз. Это происходит потому , что узлы могут хранить произвольное количество элементов смежно который является более дружественным для современных кэшей памяти.
Одна из самых больших изменений с тех пор рост кэшей. Кэш-промахи очень дорого, поэтому локальность ссылки гораздо более важно. Узел на основе структуры данных, которые имеют низкую локальность ссылок, делают гораздо меньше смысла. Если бы я проектировали СТЛ сегодня, я бы иметь различный набор контейнеров. Так, например, в памяти B * -tree является гораздо лучшим выбором, чем красно-черного дерева для реализации ассоциативного контейнера. - Александр Степанов
Вы можете прочитать здесь
Является ли красное черное дерево или B * всегда лучше?
В других случаях Алекс заявил , что std::vectorпочти всегда лучший список контейнеры по аналогичным причинам. Она редко имеет смысл использовать std::listили std::dequeдаже в тех ситуациях , мы учили в школе (например, удаление элемента из середины списка). std::vectorнастолько быстро , что он бьет эти структуры для всего , кроме большого п.
Применяя то же рассуждение , если у вас есть только небольшое число элементов (сотни?) , Используя std::vectorи линейный поиск может быть более эффективным , чем реализация структуры дерева std::map. В зависимости от частоты введения, отсортированный в std::vectorсочетании с std::binary_searchможет быть самым быстрым выбором.