Красное черное дерево над деревом авл


112

AVL и красно-черные деревья являются самобалансирующимися, за исключением красного и черного цветов в узлах. Какова основная причина выбора красно-черных деревьев вместо деревьев AVL? Каковы применения красно-черных деревьев?



1
Кстати, разработчики Rust решили использовать B-дерево вместо любого из них для своей стандартной упорядоченной карты.
Том Андерсон

Ответы:


126

Какова основная причина выбора красно-черных деревьев вместо деревьев AVL?

И красно-черные деревья, и деревья AVL являются наиболее часто используемыми сбалансированными деревьями двоичного поиска, и они гарантированно поддерживают вставку, удаление и поиск O(logN) time. Однако есть следующие точки сравнения между ними:

  • Деревья AVL более жестко сбалансированы и, следовательно, обеспечивают более быстрый поиск. Таким образом, для задачи с интенсивным поиском используйте дерево AVL.
  • Для задач с интенсивной вставкой используйте красно-черное дерево.
  • Деревья AVL хранят коэффициент баланса в каждом узле. Это требует O(N)дополнительного места. Однако, если мы знаем, что ключи, которые будут вставлены в дерево, всегда будут больше нуля, мы можем использовать знаковый бит ключей для хранения информации о цвете красно-черного дерева. Таким образом, в таких случаях красно-черное дерево не занимает лишнего места.

Какое применение красного черного дерева?

Красно-черные деревья более общего назначения. Они относительно хорошо справляются с добавлением, удалением и поиском, но деревья AVL имеют более быстрый поиск за счет более медленного добавления / удаления. Красно-черное дерево используется в следующем:

  • Ява: java.util.TreeMap ,java.util.TreeSet
  • C ++ STL (в большинстве реализаций): map, multimap, multiset
  • Ядро Linux: полностью честный планировщик, linux / rbtree.h

43
In general, the rotations for an AVL tree are harder to implement and debug than that for a Red-Black tree.это не правда.
Цзинго Яо

9
Чтобы быть педантичным, стандарт C ++ не требует этого, std:: mapи друзья используют какую-либо конкретную структуру. Это осталось на усмотрение реализации, хотя libstdc ++ и Dinkumware по крайней мере используют красно-черные деревья, и на практике кажется, что вы правы.
mbozzi

25
Коэффициент баланса, хранящийся в каждом узле дерева AVL, составляет два бита (-1 / 0 / +1). Красно-черное дерево хранит один бит информации о цвете в каждом узле. Таким образом, в сумме оба дерева требуют O (N) памяти для дополнительной информации.
Сеппо Энарви

5
«Для задач с интенсивной вставкой используйте красно-черное дерево». Зачем? Вставка дерева AVL в худшем случае занимает только один оборот, в то время как дерево Red Black может занять два.
Daniel

3
Это должно быть обновлено в соответствии с анализом производительности BST, проведенным Беном Пфаффом за 2003 год - деревья AVL более универсальны и работают лучше. Было бы интересно отследить точные исторические причины, по которым Java, C ++ и ядро ​​Linux выбрали более медленную реализацию.
Дэвид Макманамон

16

Попробуйте прочитать эту статью

Он предлагает хорошее представление о различиях, сходствах, производительности и т. Д.

Вот цитата из статьи:

RB-деревья, как и деревья AVL, самобалансируются. Оба они обеспечивают производительность поиска и вставки O (log n).

Разница в том, что RB-Trees гарантирует O (1) оборотов за операцию вставки. Вот что на самом деле стоит производительности в реальных реализациях.

Упрощенно, RB-деревья получают это преимущество от того, что они концептуально представляют собой 2-3 дерева без дополнительных затрат на динамические структуры узлов. Физически RB-деревья реализованы как двоичные деревья, красные / черные флаги имитируют 2-3 поведения.

Насколько я понимаю, деревья AVL и деревья RB не так уж далеки с точки зрения производительности. Дерево RB - это просто вариант B-дерева, и балансировка реализована иначе, чем дерево AVL.


1
AFIAK, дерево AVL также имеет поворот на O (1) за вставку. Для RB-дерева и AVL - одна вставка может иметь 1 или 0 вращений. Если происходит вращение, алгоритмы останавливаются. Если этого не происходит, обычно алгоритмы продолжают проверять / перерисовывать узлы снизу до корня дерева. Таким образом, иногда поворот O (1) может быть лучше, потому что он исключает сканирование оставшихся элементов O (log (n)). Поскольку дерево AVL в среднем делает больше вращений, дерево AVL обычно имеет лучший баланс ~ 1,44 log (N), чем RB-tree 2 log (N).
Сергей Шандар

4

Наше понимание различий в производительности улучшилось с годами, и теперь основной причиной использования красно-черных деревьев вместо AVL будет отсутствие доступа к хорошей реализации AVL, поскольку они немного менее распространены, возможно, потому, что они не охвачены в CLRS.

Оба дерева теперь считаются формами деревьев со сбалансированным рангом, но красно-черные деревья стабильно медленнее примерно на 20% в реальных тестах . Или даже на 30-40% медленнее при вставке последовательных данных .

Поэтому люди, которые изучали красно-черные деревья, но не АВЛ-деревья, склонны выбирать красно-черные деревья. Основное использование красно-черных деревьев подробно описано в статье о них в Википедии .


1
Веселая! на мой взгляд, в статье libavl, кажется, говорится, что AVL и RB равны, и ни один из них явно не лучше, чем другой в целом (какой из них лучше, зависит от рабочей нагрузки). Я не вижу нигде утверждений, что AVL в целом примерно на 20% быстрее.
Стефан

3

Другие ответы здесь хорошо суммируют плюсы и минусы деревьев RB и AVL, но я нашел эту разницу особенно интересной:

Деревья AVL не поддерживают постоянную амортизированную стоимость обновления [в отличие от красно-черных деревьев]

Источник: Mehlhorn & Sanders (2008) (раздел 7.4).

Таким образом, хотя деревья RB и AVL гарантируют наихудшее время O (log (N)) для поиска, вставки и удаления, восстановление свойства AVL / RB после вставки или удаления узла может быть выполнено за O (1) амортизированное время для красно-черные деревья.


Я считаю, что вставка дерева AVL имеет ту же / аналогичную амортизированную стоимость, но дает более сбалансированное дерево (1,44log (N) против 2log (N)). В то же время удаление в дереве AVL может потребовать большего количества вращений. ИМХО, это адрес WAVL en.wikipedia.org/wiki/WAVL_tree
Сергей Шандар

1

Программисты обычно не любят динамически выделять память. Проблема с деревом avl заключается в том, что для "n" элементов вам нужно как минимум log2 (log2 (n)) ... (height-> log2 (n)) бит для хранения высоты дерева! Поэтому, когда вы обрабатываете огромные данные, вы не можете быть уверены в том, сколько бит нужно выделить для хранения высоты в каждом узле.

Например, если вы используете 4 байта int (32 бита) для хранения высоты. Максимальная высота может быть: 2 ^ 32 и, следовательно, максимальное количество элементов, которые вы можете сохранить в дереве, составляет 2 ^ (2 ^ 32) - (кажется, очень большим, но в этом возрасте данных, я думаю, ничего не слишком велико). И, следовательно, если вы превысите этот предел, вам придется динамически выделять больше места для хранения высоты.

Это ответ, предложенный профессором моего университета, который мне показался разумным! Надеюсь, я понимаю.

Изменения: деревья AVL более сбалансированы по сравнению с красно-черными деревьями, но они могут вызывать большее вращение во время вставки и удаления. Поэтому, если ваше приложение включает в себя много частых вставок и удалений, предпочтительнее использовать деревья Red Black. И если вставки и удаления происходят реже, а поиск - более частая операция, то дерево AVL должно быть предпочтительнее красного черного дерева. --Источник GEEKSFORGEEKS.ORG


1
Я бы сказал, что это интересно, но непрактично. Хотя верно, что в самом компактном случае было бы сложно выбрать наиболее эффективное количество бит для выделения для высоты, на практике любое оставшееся пространство размером меньше байта определенно не будет использоваться, а все, что останется в 4- или даже 8-байтовом пространстве почти наверняка останется неиспользованным. Память не выделяется невыровненной по соображениям производительности, которые значительно перевешивают преимущество освобождения крошечного объема пространства. Указатели на потомков и значение занимают 24 байта; Еще 8 вряд ли будут иметь практическую стоимость.
Mumbleskates

4
you need need atleast log2(log2(n))...(height->log2(n)) bits to store the height of [an AVL] treeМне не нужна высота какого-либо узла в AVL-дереве для его реализации. Вам нужен один бит дополнительной информации для каждого узла ( Я САМЫЙ ВЕЛИКИЙ (брат с самым высоким поддеревом))); это более удобно, а также обычные иметь два дополнительных бита (ребенок выше для левой и правой), как представлено на AV & L.
глиняный кувшин

4
2 ^ (2 ^ 32) элементов - это много ... как если бы вы могли хранить каждую отдельную молекулу во всей вселенной, и каждую возможную пару этих молекул, и каждую возможную тройку, и все равно даже не приближаться к находится в пределах крошечной доли крошечного процента кубического корня из этого числа, деленного на сто квинтиллионов.
точка с запятой

4
Это вводит в заблуждение. Во-первых, нам не нужно сохранять высоту в узле дерева AVL. Во-вторых, даже если мы это сделаем, и даже если типичный объем доступной памяти удваивается каждый год, у нас все еще есть 4 миллиарда лет, пока высота наших деревьев не превысит то, что может быть сохранено в 32 битах.
Gassa

3
2 ^ (2 ^ 32) объектов - это нелепо, безумно, абсолютно больше, чем может вместить любой компьютер, который мы можем себе представить прямо сейчас. У нас что-то вроде 2 ^ 40. Снова проверь себя по математике.
Стефан Райх

-1

Повторная балансировка дерева AVL должна соответствовать следующему свойству. (Ссылка вики - AVL Tree )

В дереве AVL высота двух дочерних поддеревьев любого узла отличается не более чем на единицу; если в любой момент они отличаются более чем на единицу, выполняется повторная балансировка для восстановления этого свойства.

Таким образом, это означает, что общая высота дерева AVL не может сходить с ума, т.е. поиск будет лучше с деревьями AVL. И так как дополнительные операции (вращения) должны выполняться, чтобы не упустить высоту, операции модификации дерева могут быть немного дорогостоящими.


Он упоминается во многих других местах, но причина, по которой этот ответ не очень хорош, заключается в том, что деревья AVL и деревья RB эффективно поддерживают чрезвычайно похожие ограничения - деревья RB не будут более чем в 2,0 раза превышать требуемую высоту, а для деревьев AVL этот коэффициент равен около 1,44. Как следствие, деревья AVL вращаются немного чаще, но стоимость вращения по существу такая же; это не дорого.
Mumbleskates
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.