Удаление узла из полностью черного красного черного дерева

Я читаю объяснение Википедии о процессе удаления красно-черного дерева.

Есть одна простая вещь, которую я не могу понять.

Пример: у меня полностью черный RBTree

                     3(B)
                 /          \
                /            \
               1(B)          5(B)
             /     \        /    \
            /       \      /      \
           0(B)     2(B) 4(B)     6(B)

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

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

Что мне не хватает?

Я обнаружил, что в Википедии есть очень хорошее объяснение вставки, но объяснение удаления сбивает с толку.


person Knows Not Much    schedule 28.12.2013    source источник
comment
Википедия утверждает, что если у вас есть узел для удаления с двумя дочерними листами, а родственный узел также является узлом с двумя дочерними листами, то мы можем просто удалить узел и перекрасить родителя и родного брата. - Я не вижу этого в статье. Мне кажется, что это относится к разделу Удаление, M и C оба черные, случай 3. Ищите полужирный Случай 3 в разделе Удаление.   -  person user2357112 supports Monica    schedule 28.12.2013
comment
В этом случае в статье говорится об удалении узла, перекраске его родственного узла в красный цвет, а затем перебалансировке родителя.   -  person user2357112 supports Monica    schedule 28.12.2013
comment
Итак, как и в случае 3, мы перекрасим узел 2 в красный цвет и повторим попытку из случая 1. В этом случае... случай 1 ничего не сделает, но случай 2 повернет дерево, сделав 2 дочерним элементом 3, тогда 1R будет дочерний элемент 2 и, наконец, 0B будет дочерним элементом 1. Теперь, если мы удалим 0, b-высота в левом дереве по-прежнему будет равна 3, тогда как в правой части будет равна 4.   -  person Knows Not Much    schedule 28.12.2013
comment
не могли бы вы объяснить простой случай выше? Я не смог расшифровать ответ из википедии.   -  person Knows Not Much    schedule 29.12.2013
comment
Вы почти угадали, но затем вы допустили ошибку, перейдя к случаю 2 - вы должны были снова перейти к случаю 3, затем к случаю 1 и закончить. Смотрите мой ответ :-)   -  person Tomas    schedule 30.12.2013


Ответы (1)


Удаление узла «0» в вашем дереве на самом деле самый сложный случай. Давайте шаг за шагом следуем описанию из Википедии:

Мы используем метку M для обозначения удаляемого узла; C будет обозначать выбранного дочернего элемента M, который мы также будем называть «его дочерним элементом». Если у M есть неконечный дочерний элемент, назовите его дочерним элементом C; в противном случае выберите любой лист в качестве его дочернего элемента, C.

Итак, в этом случае M — это ваш узел «0», который будет удален, а C — любой из его дочерних элементов NIL (листья, которые всегда равны NIL). Просто напомню, что ваше исходное дерево - после вашего красивого ascii-арта:

                     3(B)
                 /          \
                /            \
               1(B)          5(B)
             /     \        /    \
            /       \      /      \
           0(B)     2(B) 4(B)     6(B)

Таким образом, M равно «0», и обратите внимание, что C (лист NIL) здесь не закрашен. Википедия следует:

Сложный случай, когда и M, и C черные (это наш случай).... На приведенных ниже диаграммах мы также будем использовать P для нового родителя N (старого родителя M), SL для Левый дочерний элемент S и SR для правого дочернего элемента S.

Итак, P — это «1», а S — это «2», все узлы черные. Затем вы следуете описаниям случаев. Вы пропускаете случай 1, так как «0» не является корневым. Вы пропускаете случай 2, так как «2» не красный. Случай 3 соответствует:

Случай 3: дети P, S и S черные. В этом случае мы просто перекрашиваем S в красный цвет. В результате все пути, проходящие через S, а это в точности те пути, которые не проходят через N, имеют на одну черную вершину меньше. Поскольку удаление исходного родителя N сделало все пути, проходящие через N, на один черный узел меньше, это выравнивает ситуацию. Однако все пути через P теперь имеют на один черный узел меньше, чем пути, не проходящие через P, поэтому свойство 5 (все пути от любого заданного узла к его листовым узлам содержат одинаковое количество черных узлов) по-прежнему нарушается. Чтобы исправить это, мы выполняем процедуру ребалансировки на P, начиная со случая 1.

Итак, в этот момент вы удаляете «0» и перекрашиваете S = «2» в красный цвет:

                     3(B)
                 /          \
                /            \
               1(B)          5(B)
                   \        /    \
                    \      /      \
                    2(R) 4(B)     6(B)

Затем, следуя описанию, вы переходите к варианту 1, но на этот раз с его родительским узлом P (= "1"), замененным на N. Но N = "1" не является корнем, поэтому вы переходите к варианту 2. S = " 5" не красный, поэтому мы снова переходим к случаю 3. И здесь мы перекрашиваем S = "5" в красный цвет:

                     3(B)
                 /          \
                /            \
               1(B)          5(R)
                   \        /    \
                    \      /      \
                    2(R) 4(B)     6(B)

Затем мы должны снова перейти к случаю 1, на этот раз заменив P = «3» на N. N = "3" и мы видим, что это корень, и так готово! Дерево сбалансировано!

person Tomas    schedule 30.12.2013