Как легко запомнить вставку и удаление Red-Black Tree? - PullRequest
32 голосов
/ 27 февраля 2012

Довольно легко полностью понять стандартное дерево бинарного поиска и его операции. Из-за этого понимания мне даже не нужно помнить реализации этих операций вставки, удаления, поиска.

Сейчас я изучаю красно-черное дерево и понимаю его свойства для поддержания сбалансированного дерева. Однако мне очень трудно понять процедуры вставки и удаления.

Я понимаю, что при вставке нового узла мы помечаем узел как красный (потому что красный - лучшее, что мы можем сделать, чтобы не нарушать меньше законов красно-черного дерева). Новый красный узел все еще может нарушать «закон о непрерывных красных узлах». Тогда мы исправим это через:

  1. проверьте цвет своего дяди, если он красный, затем отметьте его родителя и дядю как чёрного, и перейдите к бабушке и дедушке.

  2. если это правый ребенок, поверните его влево

  3. пометьте его родителя черным, а прародителя - красным, затем поверните направо прародителя.

сделано (в основном как и выше).

Во многих местах описана вставка красно-черного дерева, как указано выше. Они просто говорят вам, как это сделать. Но почему эти шаги могут исправить дерево? Почему сначала вращение влево, а затем вращение вправо?

Может кто-нибудь объяснить, почему для меня более ясно, даже более ясно, чем CLRS? В чем магия вращения?

Я действительно хочу понять, что через 1 год я могу самостоятельно реализовать красно-черное дерево, не просматривая книгу.

Спасибо

Ответы [ 6 ]

18 голосов
/ 22 февраля 2013

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

Поворот переводит дерево в состояние, в котором оно соответствует критериям перекраски (у дочернего узла есть красный дядя). Есть два ключевых различия:

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

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

Теперь давайте посмотрим, как вращение преобразует дерево, так что у нас есть дочерний узел с красным дядей и мы можем использовать перекрашивание. Я рекомендую нарисовать это, чтобы полностью понять это.

  • Пусть x будет текущим красным узлом с красным родителем.
  • Пусть p будет красным родителем x перед вращением (если бы родитель был черным, мы бы уже сделали).
  • Пусть y будет черным дядей x перед вращением (если бы дядя был красным, нам бы не понадобилось вращение. Мы просто перекрасили бы родителя и дядю в черный цвет, а прародителя в красный).
  • Пусть g будет черным прародителем x перед вращением (так как родитель красный, прародитель должен быть черным; иначе это не было красно-черное дерево с самого начала.)
  • Если у вас есть левый-левый (LL) или правый-правый (RR) регистр (то есть x - левый потомок p, а p - левый потомок g ИЛИ x - правый потомок p и p является правым потомком g), после одного поворота (вправо, если LL, оставлено, если RR), y становится дочерним, а x - его дядей. Поскольку х - красный дядя, у вас теперь есть случай, когда вы можете перекрасить. Таким образом, перекрасьте родительский элемент дочернего элемента (так как дочерний элемент теперь равен y, его родительский элемент равен g) в красный, а прародитель дочернего элемента (теперь p) - в черный.
  • Если у вас есть LR (x - левый дочерний элемент или p, а p - правый дочерний элемент g) или регистр RL (x - правый дочерний элемент p, а p - левый дочерний элемент g), после двойного поворота (затем направо, налево, если LR, затем направо, если RL), y становится ребенком, а p - дядей. Поскольку р красный дядя, у вас снова есть случай, когда вы можете перекрасить. Итак, перекрасьте родителя (так как дочерний элемент теперь у, его родительский g) в красный, а дедушка (в настоящее время х) в черный.

Перед вращением и перекрашиванием у вас был черный дедушка с 2 красными узлами и 0 черными узлами на стороне A (слева или справа) и 0 красными узлами и 1 черным узлом на стороне B (противоположной стороне A). После поворота и перекраски у вас есть черный дедушка с 1 красным узлом и 0 черными узлами на стороне A и 1 красным узлом и 1 черным узлом на стороне B. Таким образом, вы по существу переместили один из красных узлов на другое поддерево дедушка, не увеличивая черную высоту любого поддерева.

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

5 голосов
/ 27 сентября 2012

Логика довольно проста. Предположим, что z красный, а родитель z красный: Если дядя z красный, выполните шаг 1, чтобы подтолкнуть проблемный узел вверх, пока либо (1) родитель становится корнем. Затем просто отметьте черный корень. Готово или (2) дядя z черный.

В случае (2) либо (a) z является левым потомком своего родителя, тогда шаг 3 будет последним шагом, поскольку все свойства BST выполнены. Готово. или (b) z является правым потомком своего родителя. Шаг 2 преобразует проблему в случай (а). Затем сделайте шаг 3. Готово.

Таким образом, логика состоит в том, чтобы попытаться достичь случаев (1) и (2a), в зависимости от того, что наступит раньше. Это ситуации, в которых мы знаем решения.

2 голосов
/ 28 февраля 2012

игнорируйте мой (теперь удаленный) комментарий - я думаю, что код Окасаки вам поможет. если у вас есть книга («чисто функциональные структуры данных»), посмотрите текст на странице 26 и на рисунке 3.5 (лицевая сторона, стр. 27). это трудно понять.

к сожалению тезис, доступный онлайн , не имеет этой части.

Я не собираюсь его копировать, потому что диаграмма важна, но она показывает, что все разные случаи в основном одно и то же, и дает некоторый очень простой ML-код, который забивает этот дом.

[обновить] похоже, что вы сможете увидеть это на Амазонке. перейдите на страницу книги , наведите курсор мыши на изображение и введите «красный черный» в поле поиска. это дает вам результаты, которые включают страницы 25 и 26, но вам нужно войти в систему, чтобы увидеть их (очевидно - я не пробовал войти в систему, чтобы проверить).

1 голос
/ 22 октября 2014

Любое дерево 2-4 (2-3-4) можно превратить в красно-черное дерево.И понимание 2-4 деревьев намного проще.Если вы просто выполните операции вставки и удаления в 2-4 деревьях, вы почувствуете, что нет необходимости запоминать какие-либо правила для достижения того же самого.Вы увидите ясную простую логику, которая позволяет вам находить решения для различных сценариев вставки и удаления.

Как только у вас есть четкое понимание 2-4 деревьев, когда вы когда-либо сталкивались с Red-черные деревья, вы можете мысленно сопоставить эти красно-черные деревья с 2-4 деревьями и самостоятельно придумать логику.

Я нашел следующие несколько видео, которые чрезвычайно полезны для понимания 2-4 деревьев,Красно-черные деревья и отображение 2-4 деревьев на красно-черные деревья.Я бы рекомендовал просмотреть эти видео.

1) Для 2-4 деревьев: http://www.youtube.com/watch?v=JZhdUb5F7oY&list=PLBF3763AF2E1C572F&index=13

2) Для красно-черных деревьев: http://www.youtube.com/watch?v=JRsN4Oz36QU&list=PLBF3763AF2E1C572F&index=14

Evenхотя каждое видео по одному часу, я чувствовал, что его стоит посмотреть.

0 голосов
/ 21 января 2015

вы действительно делаете хороший вывод, что три случая.

после вставки в RB-Tree, осталась основная проблема, которую нужно решить, если таковая имеется.там два сплошных красных узла !!как мы можем сделать так, чтобы два непрерывных красных узла исчезли без нарушения этого правила (каждый путь имеет одинаковое количество черных узлов), чтобы мы увидели два узла, существует только 3 круга ...

Извините, вы моглисм. учебник «Инструкция к алгоритмам»

. Никакое тело не поможет вам продумать рб-дерево.они могут направить вас только в какой-то ключевой момент.

0 голосов
/ 27 сентября 2012

Возможно, стоит начать с красно-чёрных левых деревьев .Они предлагают интересную упрощенную реализацию.

...