Высота и глубина дерева: формулы и примеры
Высота и глубина дерева -- базовые характеристики древовидных структур данных: без них не обходится ни анализ алгоритмов обхода, ни оценка эффективности двоичного поиска, ни понимание балансировки. На практике многие студенты путают эти два термина, потому что оба описывают «расстояние» в дереве, но считаются в разных направлениях. Ниже разберём точные определения, выведем формулы для полного двоичного и вырожденного дерева, разберём типовые задачи. Начните с интерактивного калькулятора: задайте число уровней, выберите тип дерева и посмотрите, как меняются высота и глубина каждого уровня.
Определения: высота и глубина
Глубина узла -- это длина пути от корня до узла , то есть количество рёбер на этом пути. У корня глубина равна нулю: . У детей корня , у их детей и так далее. Формально:
Высота узла -- длина наидлиннейшего пути от узла вниз до листа:
где -- расстояние от до листа в поддереве под . У листа высота равна нулю: .
Высота дерева -- это высота корня:
Иными словами, высота дерева -- длина наидлиннейшего пути от корня до любого листа.
Формулы для полного двоичного дерева
Полное двоичное дерево -- структура, в которой каждый нелистовой узел имеет ровно двух потомков, а все листья находятся на одном уровне. Если дерево состоит из уровней (уровни ):
| Характеристика | Формула |
|---|---|
| Высота дерева | |
| Глубина узла уровня | |
| Число узлов на уровне | |
| Суммарное число узлов | |
| Число листьев |
Эти соотношения легко проверить: на уровне 0 -- один корень (), на уровне 1 -- два узла (), на уровне 2 -- четыре () и так далее. Суммарно по геометрической прогрессии:
Отсюда и обратная формула: если в полном двоичном дереве узлов, то его высота .

Высота вырожденного дерева
Вырожденное (или патологическое) дерево -- это крайний случай: каждый нелистовой узел имеет ровно одного потомка. Такое дерево структурно эквивалентно связному списку. При узлах:
Алгоритм двоичного поиска в таком дереве деградирует до линейного: на каждом уровне одна ветвь, поэтому поиск элемента требует шагов вместо в сбалансированном дереве. Именно для предотвращения вырождения придуманы AVL-деревья и красно-чёрные деревья -- они гарантируют, что высота не превысит .
Рассмотрим пример: вставим ключи в BST без балансировки в порядке возрастания. Каждый новый ключ окажется правым потомком предыдущего, и дерево вытянется в прямую линию. Глубина узла со значением 5 будет равна 4, высота всего дерева тоже 4 -- хотя в полном двоичном дереве из 5 узлов . Это наглядно показывает, насколько важна очерёдность вставки для неавтобалансирующихся деревьев.
Рекурсивный алгоритм вычисления высоты
Высоту дерева можно найти рекурсивно: высота пустого дерева равна (или в соглашении «считаем узлы»), высота листа -- , высота нелистового узла -- максимум высот его поддеревьев плюс единица:
Псевдокод:
def height(node):
if node is None:
return -1
return 1 + max(height(node.left), height(node.right))
Алгоритм обходит каждый узел ровно один раз, поэтому временная сложность -- , а пространственная -- (глубина стека рекурсии).
Глубина узла считается иначе -- не рекурсией вниз, а обходом вверх (или сверху вниз с передачей текущей глубины):
def depth(node, target, d=0):
if node is None:
return -1
if node == target:
return d
left = depth(node.left, target, d + 1)
if left != -1:
return left
return depth(node.right, target, d + 1)
Связь между высотой и числом узлов
Для любого двоичного дерева с узлами высота удовлетворяет двусторонней оценке:
Левая граница достигается на полном дереве, правая -- на вырожденном. Это неравенство объясняет, почему инженеры так заботятся о балансировке: разница между и для больших огромна. Например, при : против .
Высота в стандартных структурах данных
Высота имеет прямое значение в нескольких структурах:
- Двоичное дерево поиска (BST). Без балансировки высота зависит от порядка вставки: при случайных ключах ожидаемая , в худшем случае (вставка уже отсортированного ряда).
- AVL-дерево. Гарантирует . Балансировка выполняется поворотами при нарушении «баланс-фактора» ( в каждом узле).
- Красно-чёрное дерево. Гарантирует .
- Куча (heap). Хранится в массиве, логически образует полное дерево; высота .
- B-дерево. Используется в базах данных и файловых системах; каждый узел хранит от до ключей (параметр -- минимальная степень). Высота B-дерева не превышает , что позволяет существенно сократить число дисковых операций по сравнению с двоичными деревьями.
Зная высоту дерева в конкретной реализации, можно сразу оценить трудоёмкость операций. Например, в AVL-дереве с узлов -- это означает не более 29 сравнений при поиске, независимо от того, в каком порядке вставлялись данные.
Частые ошибки
- Путаница «высота» и «глубина». Глубина -- свойство узла (расстояние от корня вниз), высота -- тоже свойство узла, но в обратном направлении (от него до листа). Высота дерева = высота корня. Новички нередко подставляют глубину туда, где нужна высота.
- Несогласованность соглашения о нумерации. В одних источниках высота листа равна 0, в других -- 1. Число уровней и высота тоже соотносятся по-разному ( или ). Перед решением задачи уточни, какое соглашение принято.
- Неверная рекурсия для пустого поддерева. Если возвращать , а не , листья получат высоту 1 вместо 0. Это сдвигает все значения на единицу.
- Смешение высоты дерева и максимальной глубины листа. Оба значения совпадают по определению, но при реализации через разные алгоритмы (сверху вниз и снизу вверх) легко получить расхождение из-за ошибки в базовом случае.
- Игнорирование вырождения при вставке. При вставке уже отсортированного массива в BST без балансировки дерево вырождается в список: высота становится вместо .
FAQ
Чем отличается высота от глубины в дереве? Глубина узла -- расстояние от корня до этого узла (метрика сверху вниз). Высота узла -- длина самого длинного пути от этого узла до листа (метрика снизу вверх). У одного и того же узла глубина и высота обычно разные числа; совпадают только в вырожденных случаях.
Как посчитать высоту двоичного дерева с n узлами? Зависит от структуры дерева. Для полного двоичного дерева с уровнями . Для произвольного BST из узлов -- рекурсивно: , . Нижняя оценка: .
Почему высота влияет на скорость операций в дереве? Операции поиска, вставки и удаления в BST занимают шагов: на каждом шаге спускаемся на один уровень. При сбалансированном дереве -- быстро. При вырождении -- медленно, как линейный поиск. Поэтому балансировка деревьев так важна для производительности.
Коротко
Глубина узла -- расстояние от корня до узла, высота узла -- длина длиннейшего пути вниз до листа. Высота дерева -- это высота корня. Для полного двоичного дерева с уровнями: , на уровне ровно узлов, всего . Вырожденное дерево из узлов имеет -- это нижний предел эффективности, который балансировка (AVL, красно-чёрное дерево) сводит к .
Читайте также

Задача о рюкзаке: динамическое программирование
Разбор задачи о рюкзаке (0/1 Knapsack) методом ДП: таблица dp[i][w], рекуррентный переход, traceback-восстановление набора. Пошаговые примеры и анализ сложности O(n*W).

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

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