Почему необходимо окрашивать корень в черный цвет после каждой вставки в лево-наклонное красно-черное дерево? - PullRequest
0 голосов
/ 10 января 2019

В лево-наклонных красно-черных деревьях Седжвика (представленных в его статье или его книге "Алгоритмы ") одна модификация стандартного BST - окрашивать корневой узел в черный цвет после каждого вставка, см. root.color = BLACK в insert(Key, Value).

Я понимаю, что семантически это необходимо, потому что корневой узел никогда не должен быть левым подузлом 3-узла / 4-узла. Однако я не могу понять, почему это необходимо на практике, поскольку кажется, что цвет корневого узла никогда не проверяется. Может ли кто-нибудь указать, что мне здесь не хватает?

Ответы [ 4 ]

0 голосов
/ 12 января 2019

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

0 голосов
/ 12 января 2019

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

Итак, я немного протестировал, чтобы попытаться подтвердить это, и в процессе я обнаружил, что в коде, представленном в этой статье, на самом деле есть куча небольших ошибок: вызовы методов, которые никогда не определяются, присвоения переменных, которые никогда не объявляются, ненужное повторение дорогих вызовов методов, неиспользуемые ссылки на объекты (= указатели) и т. д.

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

Но что бы это ни стоило, мои тесты показывают, что основной цвет действительно не имеет значения; Я написал метод проверки, который проверяет соответствующие инварианты (что ни один красный некорневой узел не имеет красного потомка, и что все конечные узлы имеют одинаковую глубину черного), и я обнаружил, что они были сохранены независимо от того, Не я закомментировал строки, чтобы установить корневой цвет на черный. (Конечно, это демонстрирует это только для случаев, которые я тестировал, но все же этого было достаточно, чтобы придать мне большую уверенность в заключении. В частности, мои случаи включали добавление ключей от 1 до 1000 по порядку, в обратном порядке или случайным образом. в порядке перемешивания, затем удаляя их по порядку, в обратном порядке или в случайном порядке. Я проверял инварианты после каждой отдельной вставки или удаления.)

0 голосов
/ 12 января 2019

Похоже, что для стандартных красно-черных деревьев это не отличается: корень должен быть черным. Это не более чем соглашение, поскольку в теории корневой узел может быть (слева) красным, не нарушая ни одного из (других) свойств красно-черного дерева. Такое изменение цвета также не влияет на дополнительные свойства для красно-черных деревьев, расположенных слева.

См. Свойство № 2 в Красно-черное дерево - Википедия :

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

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

0 голосов
/ 10 января 2019

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

...