коротко и ясно / Хабр
История из жизни. Девушка предложила своему парню-программисту пройти психологический тест:
Девушка: Нарисуй дерево.
Программист: (рисует бинарное дерево)
Девушка: Нет, другое.
Программист: Я и красно-черное дерево могу нарисовать.
Итак, сегодня хочу немного рассказать о красно-черных деревьях. Рассказ будет кратким, без рассмотрения алгоритмов балансировки при вставке/удалении элементов в красно-черных деревьях.
Красно-черные деревья относятся к сбалансированным бинарным деревьям поиска.
Как бинарное дерево, красно-черное обладает свойствами:
1) Оба поддерева являются бинарными деревьями поиска.
2) Для каждого узла с ключом выполняется критерий упорядочения:
ключи всех левых потомков <= < ключи всех правых потомков
(в других определениях дубликаты должны располагаться с правой стороны либо вообще отсутствовать).
Это неравенство должно быть истинным для всех потомков узла, а не только его дочерних узлов.
Свойства красно-черных деревьев:
1) Каждый узел окрашен либо в красный, либо в черный цвет (в структуре данных узла появляется дополнительное поле – бит цвета).
2) Корень окрашен в черный цвет.
3) Листья(так называемые NULL-узлы) окрашены в черный цвет.
4) Каждый красный узел должен иметь два черных дочерних узла. Нужно отметить, что у черного узла могут быть черные дочерние узлы. Красные узлы в качестве дочерних могут иметь только черные.
5) Пути от узла к его листьям должны содержать одинаковое количество черных узлов(это черная высота).
Ну и почему такое дерево является сбалансированным?
Действительно, красно-черные деревья не гарантируют строгой сбалансированности (разница высот двух поддеревьев любого узла не должна превышать 1), как в АВЛ-деревьях. Но соблюдение свойств красно-черного дерева позволяет обеспечить выполнение операций вставки, удаления и выборки за время .
Пусть у нас есть красно-черное дерево. Черная высота равна (black height).
Если путь от корневого узла до листового содержит минимальное количество красных узлов (т.е. ноль), значит этот путь равен .
Если же путь содержит максимальное количество красных узлов ( в соответствии со свойством ), то этот путь будет равен .
То есть, пути из корня к листьям могут различаться не более, чем вдвое (, где h — высота поддерева), этого достаточно, чтобы время выполнения операций в таком дереве было
Как производится вставка?
Вставка в красно-черное дерево начинается со вставки элемента, как в обычном бинарном дереве поиска. Только здесь элементы вставляются в позиции NULL-листьев. Вставленный узел всегда окрашивается в красный цвет. Далее идет процедура проверки сохранения свойств красно-черного дерева .
Свойство 1 не нарушается, поскольку новому узлу сразу присваивается красный цвет.
Свойство 2 нарушается только в том случае, если у нас было пустое дерево и первый вставленный узел (он же корень) окрашен в красный цвет. Здесь достаточно просто перекрасить корень в черный цвет.
Свойство 3 также не нарушается, поскольку при добавлении узла он получает черные листовые NULL-узлы.
В основном встречаются 2 других нарушения:
1) Красный узел имеет красный дочерний узел (нарушено свойство ).
2) Пути в дереве содержат разное количество черных узлов (нарушено свойство ).
Подробнее о балансировке красно-черного дерева при разных случаях (их пять, если включить нарушение свойства ) можно почитать на wiki.
Это вообще где-то используется?
Да! Когда в институте на третьем курсе нам читали «Алгоритмы и структуры данных», я и не могла представить, что красно-черные деревья где-то используются. Помню, как мы не любили тему сбалансированных деревьев. Ох уж эти родственные связи в красно-черных деревьях («дядя», «дедушка», «чёрный брат и
красный отец»), прям Санта-Барбара какая-то. Правые и левые, малые и большие повороты АВЛ-деревьев – сплошные американские горки. Вы тоже не любите красно-черные деревья? Значит, просто не умеете их готовить. А кто-то просто взял и приготовил. Так, например, ассоциативные массивы в большинстве библиотек реализованы именно через красно-черные деревья.
Это все, что я хотела рассказать.
Понимаем красно-черное дерево. Часть 1. Введение / Хабр
Часть 1. Введение
Часть 2. Балансировка и вставка
Довольно долгое время я воевал с красно-черным деревом (далее — кчд). Вся информация, которую я находил, была в духе «листья и корень дерева всегда черные, ПОТОМУ ЧТО», «топ 5 свойств красно-черного дерева» или «3 случая при балансировке и 12 случаев при удалении ноды». Такой расклад меня не устраивал.
Мне не хотелось заучивать свойства дерева, псевдокод и варианты балансировки, я хотел знать: почему. Каким образом цвета помогают при балансировке? Почему у красной ноды не может быть красного потомка? Почему глубину дерева измеряют «черной высотой»?
Ответы на эти вопросы я получил только тогда, когда мне дали ссылку на лекцию про два-три дерево, с которого мы и начнем.
Эта статья разделена на 3 логические части. Я рекомендую прочитать их в указанном порядке. Первая часть (данная) будет направлена на введение в кчд и знакомство с ним. Во второй части мы поговорим о балансировке и вставке в кчд. В третьей, завершающей, части мы разберем процесс удаления ноды. Наберитесь терпения и приятного чтения:)
Дисклеймер
В этой статье не будет информации про плюсы и минусы дерева, его применение и т.д.: информации об асимптотике дерева и работе с ним в интернете полно.
Материал предназначен для тех, кто уже знаком с кчд и теперь хочет их понять, а также для тех, кто только знакомится с ними.
Статья не будет содержать деталей реализации структуры.
Можно считать что эта статья — перевод английского видео материала в упрощенный русский текстовый вариант. Все ссылки я оставляю в конце статьи.
Два-три дерево
Чтобы понять красно-черное дерево, нужно понять два-три дерево
Забегая вперед, скажу, что два-три дерево — это, по сути, родитель нашего кчд, поэтому важно начать именно с него. Поймем два-три дерево — поймем и кчд.
Два-три дерево — абстрактный тип данных, напоминающий по структуре дерево. В нодах два-три дерева может быть одно или два значения и два или три потомка (от чего зависит количество значений и потомков ноды, узнаем ниже). Ноду с одним значением и двумя потомками будем называть 2-нода, ноду с двумя значениями и тремя потомками — 3-нода. Объяснение я начну с создания такого дерева: это наглядно и просто. Но некоторые уточнения нужны все же вначале:
Добавляя элемент, мы всегда спускаемся вниз по дереву.
Дерево отсортировано классически — меньшие значения находятся слева, бОльшие — справа.
Два-три дерево — отсортированное, сбалансированное дерево.
Итак, начнем с первой ноды, это число 5. Тут все просто — 5 становится корнем.
Добавим число 12. Число 12 мы так же добавляем в корень (помним, что нода может иметь два значения), но теперь нам нужно «отсортировать» нашу ноду (сортировать два элемента, ха), т. е. уложить их в порядке возрастания. В итоге получается нода 5-12.
Добавим следующее число. Пусть это будет 17. Давайте пока добавим наш элемент в единственную ноду и снова отсортируем ее. Получилась нода 5-12-17.
Внимательный читатель заметит тут подвох — выше я говорил о том, что наши ноды могут содержать не более двух элементов. Вот тут и происходит магия! Мы берем средний элемент нашей ноды и «просачиваем» его наверх. Итог виден на картинке. Корнем стало число 12, левым сыном число 5, правым — 17.
То, что мы сделали выше, можно назвать балансировкой два-три дерева. Правило в этой балансировке простое: если в ноде оказывается три значения, среднее значение мы «просачиваем» вверх. Алгоритм действий зависит от 3 условий:
Нода является корнем. Тогда ничего не остается, как создать новую ноду с одним значением и сделать ее новым корнем (как в нашем случае).
Родительская нода имеет одно значение. Тогда мы просто добавляем значение к родителю и завершаем балансировку (при этом у родителя появляется третий потомок).
Родительская нода имеет два значения. Тогда мы снова просачиваем значение вверх, пока не придем к пункту один или два.
Второй и третий случай балансировки будут рассмотрены ниже.
Окей, идем дальше. Давайте добавим число 3. Так как теперь мы не ограничиваемся одной нодой, спускаемся вниз. Понятно, что спуститься надо влево и добавить 3 к ноде со значением 5. Не забываем расставить 3 и 5 в нужном порядке. В итоге получилась нода 3-5.
Потерпите, мы близимся к самому интересному:)
Давайте добавим число 4 которое также пойдет влево и присоединится к ноде 3-5. Получится нода 3-4-5, которую, как мы уже знаем, нужно привести к нужному виду. Что делаем? Балансируем наше дерево, т.е. «просачиваем» значение 4 наверх.
Теперь самое интересное. Помимо того, что мы добавим 4 к корню, мы так же добавим корню третьего потомка — это будет нода, которая была больше 4. В нашем случае это 5. Картина будет выглядеть так:
Почему 5 не могла остаться на месте в своей ноде? Тут мы вспоминаем правило отсортированного дерева: значения меньше — слева, значения больше — справа. И так как 5 больше 4, мы не можем оставить 5 слева, т.к. это нарушит наш инвариант. Поэтому ноде со значением 5 ничего не остается, как «переехать», и стать потомком ноды 4-12 (кстати, если бы у 5 были потомки, они так же «переехали» бы вместе с родителем).
Тут нужно сделать небольшую паузу и объяснить, как ориентироваться в нодах с тремя потомками. Все просто:
Значение, что меньше левого значения в ноде, будет левым потомком.
Значение, что больше левого, но меньше правого значения в ноде, будет средним потомком.
Значение, что больше правого значения в ноде, будет правым потомком.
А теперь посмотрите на то, что получилось. Смело можно заявить, что это отсортированное, сбалансированное два-три дерево. Значения меньше лежат слева, значения больше — справа (тут, как и в случае со значениями 4-5-12, мы считаем, что 5 лежит справа от 4 и слева от 12). Корень имеет два значения и три потомка, что абсолютно соответствует описанию дерева выше. Сейчас вы можете сами попробовать добавить любое значение, чтобы удостовериться, что вы поняли логику (что произойдет с деревом, если добавить значение 7? А затем 9?).
Окей, с самим деревом, я надеюсь, разобрались. Ноды добавляются, дерево балансируется, искать можно, все супер. Но есть нюансы.
Главный минус такой структуры в том, что она, в отличие от бинарного дерева, неудобна в реализации. Нужно следить за количеством потомков и значением, плюс за их порядком, балансировкой (и это я еще не говорил про удаление). Красно-черное дерево решает эту проблему.
Красно-черное дерево
Как мы выяснили, главный недостаток два-три дерева — его структура. Тогда давайте попробуем превратить два-три дерево в дерево бинарное. Как мы можем сделать это?
Чтобы добиться этого, нам нужно простое представление для 3-ноды. Давайте разделим 3-ноду на две 2-ноды и свяжем их ссылками. Пометим эти ссылки каким-нибудь свойством, например, цветом, (возьмём красный), чтобы отличать такие ссылки в дереве от всех остальных.
Вообще говоря, мы не можем пометить сами ссылки, поэтому мы помечаем ноды.
Итак, перед вами красно-черное дерево. Далее, мы разберем несколько свойств кчд, которые я считаю важными (но я думаю, что уже из прочитанного выше многое стало ясно).
Свойства красно-черного дерева
СпойлерФактически мы разбираем не просто кчд, а левосторонне кчд — одна из имплементаций кчд, в которой красные ноды могут находится только слева, то есть от 3-ноды мы всегда отделям значение меньше (что и было сделано выше). По сути своей левостороннее кчд ничем не отличается от обычного, за исколючением того, что это более простая и понятная имплементация. Аналогично левостороннему кчд, существует и правостороннее кчд(логику его додумайте сами).
Свойство 1.
Две красные ноды не могут идти подряд. Это свойство приобретает смысл, если мы знаем, что красная нода — это по сути часть 3-ноды в 2-3 дереве. Ну а если две красные ноды идут подряд, то получается 4-нода, которой у нас не существует:)
Свойство 2.
Корень дерева всегда черный. Опять же, тут все понятно: красная нода не может существовать без родителя.
Свойство 3.
Все null-ноды (ноды, которые не имеют потомков) — черные. Почему именно так, для себя объяснений я не нашел. Но хочу сказать, что это довольно удобное правило, когда дело доходит до балансировки дерева.
Про потомковРаз уж мы затронули null-ноды, то стоит сказать, что в дереве у всех нод всегда должно быть два потомка, а если ссылка на потомка нулевая, то ведет она как раз в null-ноду. На самом деле, тут встает вопрос в реализации, мне было удобнее добавлять null-ноду(меньше проблем с итераторами, балансировкой и прочим).
Свойство 4.
Высота дерева измеряется только по черным нодам и называется «черной высотой». Тут опять все в целом становится очевидным: красная нода является только дополнением к ноде черной, является ее частью, поэтому высоту принято считать по черным нодам.
На этом введение подходит к концу. В следующей части мы поговорим о том, как вставлять ноды в дерево и балансировать его.
Грузия Спорт | redandblack.com
Еще от спортивного отдела
Женский теннис из Джорджии выиграл девятый турнир SEC
- Обновлено
Алексис Райан и Брайан Гомес забрали домой золото в Афинах Twilight Criterium
Алексис Райан и Брайан Гомес, представляющие L39ION из Los Angeles Nights и Miami Nights соответственно, заняли первое место в субботнем вечере в Афинах Twilight Criterium.
Героизм поздней игры продвигает бейсбол Джорджии мимо Арканзаса
Первый игрок с низов Джорджии Паркс Харбер подошел к пластине в конце девятого иннинга. Бейсбольная команда Джорджии только что сравнялась с Арканзасом, 8-8, и без аутов все внимание было приковано к юниору из Атланты.
Бейсбол Джорджии обыграл Арканзас 9-8 с розыгрышем хоумрана на последней минуте
В субботу, 22 апреля, бейсбольная команда Джорджии выиграла со счетом 9:8 над № 5 из Арканзаса, забив пять очков на последних минутах игры, характеризующейся неравномерной защитой и борьбой с КПЗ. Эта победа знаменует собой первый розыгрыш SEC в Грузии в этом сезоне.
Предварительный просмотр драфта НФЛ: Бродерик Джонс
- Обновлено
В преддверии драфта НФЛ 2023, который пройдет 27-29 апреля, The Red & Black просматривает каждого из 14 проспектов Джорджии. Далее идет атакующий лайнмен Бродерик Джонс.
Женская теннисистка Грузии вышла в полуфинал турнира SEC
- Обновлено
На этой неделе теннисистка № 4 из Джорджии отправилась в Фейетвилл, штат Арканзас, чтобы принять участие в женском турнире SEC Championship. В пятницу вечером Грузия обыграла LSU в четвертьфинале со счетом 4: 0.
Мужская теннисная команда Джорджии обыграла Флориду со счетом 4:0 и вышла в полуфинал SEC
- Обновлено
В пятницу, 21 апреля, мужская теннисная команда Джорджии, сеяная под номером 1, обыграла сеяную под номером 8 Флориду со счетом 4:0 в Оберне, штат Алабама, в Теннисном центре Ярбро во время первого матча команды Чемпионат СЭК.
Бывший нападающий Иллинойса Р.Дж. Мелендес переходит в Джорджию
Бывший нападающий «Иллинойса» Рамзес «RJ» Мелендес объявил о своем намерении перейти в Джорджию в посте в Instagram 17 апреля.
3-звездочный ресивер 2024 года NiTareon Tuggle отправляется в Грузию
11 апреля Нитареон Таггл, перспективный приемник из класса 2024, поступил в Университет Джорджии.
Бейсбольный мяч Джорджии обыграл № 5 Арканзаса со счетом 7: 3 и выиграл вторую серию 9 SEC.0008
- Обновлено
В пятницу, 21 апреля, бейсбольная команда Джорджии обыграла № 5 Арканзаса со счетом 7: 3 во второй игре серии из трех игр команд. Эта победа принесла Грузии вторую победу в серии SEC за весь сезон и третью победу в серии над соперником из топ-25.
О красном и черном | Сайт
Поиск по сайту
The Red & Black Publishing Company, Inc. — независимая частная некоммерческая корпорация. Газета, основанная в 1893 году, в течение 87 лет работала при Университете Джорджии. В 1980 году Попечительский совет штата утвердил независимый статус организации.
Сегодня мы работаем как некоммерческая организация, преследующая двойную цель: дать студентам практическое обучение новостной индустрии и предоставить нашему сообществу надежные, независимые новости и информацию.
Управляемый студентами отдел новостей Red & Black освещает Университет Джорджии и Афины, предлагая ежедневные сообщения о новостях, спорте, искусстве, культуре и многом другом на redandblack. com, а также еженедельную газету, которая является крупнейшей газетой колледжа в Джорджии. В 2019 году The Red & Black получила национальную награду Mark of Excellence от Общества профессиональных журналистов как лучшая ежедневная студенческая газета в стране.
В дополнение к отделу новостей The Red & Black Publishing Company выпускает ряд отмеченных наградами специальных изданий, в том числе UGA 101, путеводитель для первокурсников, и Eat & Drink Athens, GA, путеводитель по местным ресторанам и барам. Мы также проводим специальные мероприятия, такие как ежегодная ярмарка жилья.
До 250 студентов в год участвуют в The Red & Black, осваивая такие навыки, как журналистика, фотография, цифровое производство, видеосъемка, монтаж, графический дизайн и управление социальными сетями. Помимо отдела новостей, студенты также работают над продажами рекламы, товарными программами, дизайном рекламы и другими аспектами деятельности корпорации.
The Red & Black функционально и финансово независима от Университета Джорджии. Организация не получает плату за студенческую деятельность или другое финансирование от UGA. Операции поддерживаются за счет продажи рекламы и пожертвований.
Как некоммерческая организация 501(c)(3), The Red and Black управляется добровольным советом директоров. Совет директоров назначает генерального директора, главного редактора и студенческого менеджера по рекламе для выполнения повседневных обязанностей по публикации газеты и цифровых продуктов.
Быстрые ссылки
Персонал | Список действующих сотрудников можно найти здесь.
Присоединиться | Чтобы узнать больше о присоединении к студенческому коллективу The Red & Black, нажмите здесь.
Выпуски новостей | Получайте последние новости от The Red & Black здесь.
Выпускники | Найдите новости о тысячах выпускников Red & Black и отправьте свои собственные новости здесь.