11

Что такое деревья и как с ними работать. Используем Java

Серия Деревья

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

Деревья бывают разные. Мы рассмотрим двоичное сбалансированное.

В данной статье мы рассмотрим наиболее популярные — двоичные сбалансированные (красно-черные) деревья.

Пример бинарного дерева. У каждого листка может быть не более двух наследников.

Пример бинарного дерева. У каждого листка может быть не более двух наследников.

Основные понятия.

Рассматривая бинарные деревья нужно знать следующие понятия:

  • Node - он же узел. Это элемент дерева, содержащий какое-то значение, которое может быть любым, от примитива (например, числа) до объекта (например, пользователя).

  • Edge или ребро. Ссылка, соединяющая один узел с другим или указывающая на пустое значение (null).

  • Root Node. Верхний узел дерева, от которого начинается вся структура.

  • Leaf - Узел, не имеющий наследников, то есть находящийся в самом низу иерархии.

  • Высота дерева - Количество "уровней", от корня до самого нижнего узла.

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

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

деградированное дерево вырожденное в связанный список.

деградированное дерево вырожденное в связанный список.

Сбалансированные деревья.

Сбалансированные (например красно-черные) при каждом добавлении нового узла проверяют, является ли дерево "несбалансированным". Если условие истино то дерево делает "разворот" свои узлов.

Пример красно черного сбалансированного дерева. Именно такое используется в TreeMap

Пример красно черного сбалансированного дерева. Именно такое используется в TreeMap

Сбалансированные деревья никогда не вырождаются в связанные списки. В J ava джаве деревья представлены коллекцие TreeMap и TreeSet (который инкапсулирует TreeMap внутри себя).

Как могут быть представлены деревья на уровне кода.

Если мы не используем готовые решения вроде TreeMap то простейшее дерево может быть представлено в виде следующего класса:

Простейший узел. По большому счету это единственный важный момент.

Простейший узел. По большому счету это единственный важный момент.

Итого что мы имеем:

  • String data это то значение которое хранит узел. Это может быть любым объектом - в нашем случае просто строка.

  • Node left - ссылка на левого наследника.

  • Node right - ссылка на правого.

Используя Node класс создадим дерево

Поочередно инициализируем наше дерево с 7 узлами

Изобразим полученное дерево:

Итерация по дереву - один из самых важных навыков для решения задач.

Большинство (если не все) задач, связанных с деревьями требуют итерации или обхода узлов. Чаще всего, умея обходить дерево, вы решаете львиную часть проблемы. В данной статье мы рассмотрим лишь 1 вариант итерации, я напишу отдельные статьи чтобы рассмотреть другие подходы.

Используем рекурсию для итерации и распечатки всех элементов.

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

Код вроде простой но не стоит его недооценивать. Давайте проговорим этапы:

  1. Распечатываем значение узла

  2. Идем к левому наследнику и повторяем действие (те опять распечатываем и идем влево)

  3. после того мы обошли все левые и уткнулись в null мы "возвращаемся" на уровень который находится наверху от нижнего левого и идем в правый наследник

  4. зайдя в правый распечатывем и идем влево повторяя шаги 2-3.

Все это звучит странно проще будет изобразить:

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

Кому интересна разработка приглашаю в мой телеграм канал

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества