Дерево — это связный ациклический граф. Связность означает наличие путей между любой парой вершин, ацикличность — отсутствие циклов и то, что между парами вершинами имеется только по одному пути. Ориентированное (направленное) дерево -ориентированный граф, не содержащий циклов) Дерево не имеет кратных рёбер и петель. Любое дерево с вершинами содержит ребро. Более того, конечный связный граф является деревом тогда и только тогда, когда , где — число вершин, — число рёбер графа. Граф является деревом тогда и только тогда, когда любые две различные его вершины можно соединить единственным элементарным путём. Любое дерево однозначно определяется расстояниями (длиной наименьшей цепи) между его концевыми (степени 1) вершинами. Для любых трёх вершин дерева, пути между парами этих вершин имеют ровно одну общую вершину. Двои́чное де́рево — древовидная структура данных, в которой каждый узел имеет не более двух потомков (детей). Как правило, первый называется родительским узлом, а дети называются левым и правым наследниками. Для практических целей обычно используют два подвида бинарных деревьев — двоичное дерево поиска и двоичная куча. Общее применение управление иерархией данных; упрощение поиска информации (см. обход дерева); управление сортированными списками данных; синтактический разбор арифметических выражений , оптимизация программ; в качестве технологии компоновки цифровых картинок для получения различных визуальных эффектов; форма принятия многоэтапного решения Двоичное дерево поиска — это двоичное дерево, для которого выполняются следующие дополнительные условия Свойства дерева поиска: Оба поддерева — левое и правое, являются двоичными деревьями поиска. У всех узлов левого поддерева произвольного узла X значения ключей данных меньше, нежели значение ключа данных самого узла X. В то время, как у всех узлов правого поддерева того же узла X значения ключей данных не меньше, нежели значение ключа данных узла X. Для различных операций двоичное дерево поиска можно определить так: Двоичное дерево состоит из узлов (вершин) — записей вида (data, left, right), где data — некоторые данные привязанные к узлу, left и right — ссылки на узлы, являющиеся детьми данного узла - левый и правый сыновья соответственно. Для оптимизации алгоритмов конкретные реализации предполагают также определения поля parent в каждом узле (кроме корневого) - ссылки на родительский элемент. Данные (data) обладают ключом (key), на котором определена операция сравнения "меньше". В конкретных реализациях это может быть пара (key, value) - (ключ и значение), или ссылка на такую пару, или простое определение операции сравнения на необходимой структуре данных или ссылке на неё. Для любого узла X выполняются свойства дерева поиска: key[left[X]] < key[X] ≤ key[right[X]], т. е. ключи данных родительского узла больше ключей данных левого сына и нестрого меньше ключей данных правого. Основным преимуществом двоичного дерева поиска перед другими структурами данных является возможная высокая эффективность реализации основанных на нём алгоритмов поиска и сортировки. Есть три способа обхода: Прямой Поперечный Обратный Префиксный (прямой) обход — сначала обрабатывается текущий узел, затем левое и правое поддеревья; Префиксный обход: A, B, D, H, E, C, F, I, J, G Инфиксный (симметричный) обход — сначала обрабатывается левое поддерево текущего узла, затем корень, затем правое поддерево; инфиксный обход: D, H, B, E, A, I, F, J, C, G Постфиксный (обратный) обход — сначала обрабатываются левое и правое поддеревья текущего узла, затем сам узел. постфиксный обход: H, D, E, B, I, J, F, G, C, A 1. Двои́чная куча, пирамида, или сортирующее де́рево — такое двоичное дерево, для которого выполнены три условия: 2. Значение в любой вершине не меньше, чем значения её потомков. 3. Глубина листьев (расстояние до корня) отличается не более чем на 1 слой. 4. Последний слой заполняется слева направо. 5. Также двоичная куча просто реализуемая структура данных, позволяющая быстро (за логарифмическое время) добавлять элементы и извлекать элемент с максимальным приоритетом (например, максимальный по значению). class Heap { int[] data; // массив с элементами (индексация с 1, 0 - фиктивная вершина) int pnt = 0; // указаетель на последний элемент /* Конструктор */ Heap(int size) { data = new int [size + 1]; } /* Добавить элемент */ void add(int x) { data[++pnt] = x; for (int v = pnt, p = v >> 1; p > 0 && data[p] > data[v]; swap(data, p, v), v = p, p >>= 1); } /* Извлечь минимум */ int extractMin() { int ret = data[1]; swap(data, 1, pnt--); for (int v = 1; (v << 1) <= pnt; ) { int l = v << 1; int r = l + 1; if (r <= pnt && data[r] < data[l] && data[r] < data[v]) swap(data, v, v = r); else if (data[l] < data[v]) swap(data, v, v = l); else break; } return ret; } }