Введение

Структура данных, представляющая собой дерево, в котором у каждого узла не более m потомков. В теории графов, m-арное дерево (для неотрицательных целых чисел m) (также известное как n-арное, k-арное или k-путевое дерево) является арборесценцией (или, по мнению некоторых авторов, упорядоченным деревом), в котором каждый узел имеет не более m потомков. Двоичное дерево является важным частным случаем при m = 2; аналогично, троичное дерево – это дерево, при m = 3.

Типы деревьев

Полное m-арное дерево — это m-арное дерево, в котором на каждом уровне каждый узел имеет 0 или m потомков. Полное m-арное дерево (или, реже, совершенное m-арное дерево) — это полное m-арное дерево, в котором все листовые узлы находятся на одной и той же глубине.

Продольные методы для м-арных деревьев

Пересечение m-арного дерева очень похоже на пересечение двоичного дерева. Обход в предварительном порядке осуществляется к родительскому узлу, затем к левому поддереву и правому поддереву, а обход в постфиксном порядке – по левому поддереву, правому поддереву и, наконец, к родительскому узлу. Для обхода в инфиксном порядке, поскольку у узла более двух детей при m > 2, необходимо определить понятия левого и правого поддеревьев. Один из распространенных способов определения левого и правого поддеревьев – разделить список дочерних узлов на две группы. Определив порядок для m детей узла, первые узлов будут составлять левое поддерево, а узлов – правое поддерево.

Преобразовать двойное дерево в двойное дерево

Использование массива для представления m-арного дерева неэффективно, поскольку большинство узлов в практических приложениях имеют менее m потомков. В результате это приводит к разреженному массиву с большим объемом неиспользуемой памяти. Преобразование произвольного m-арного дерева в двоичное дерево увеличит высоту дерева лишь на постоянный множитель и не повлияет на общую сложность времени в худшем случае. Иными словами, сначала мы связываем все непосредственные дочерние узлы данного родительского узла в связный список. Затем мы сохраняем связь от родителя к первому (то есть, крайнему левому) потомку и удаляем все остальные связи с остальными потомками. Мы повторяем этот процесс для всех потомков (если они имеют потомков), пока не обработаем все внутренние узлы и не повернем дерево на 45 градусов по часовой стрелке. Полученное дерево является желаемым двоичным деревом, полученным из исходного m-арного дерева.

Массивы

m-арные деревья также могут храниться в порядке обхода в ширину как неявная структура данных в массивах, и если дерево является полным m-арным деревом, этот метод не приводит к потерям памяти. В этой компактной организации, если узел имеет индекс i, его c-й потомок (где c находится в диапазоне от 1 до m) находится по индексу , а его родитель (если он есть) – по индексу (при условии, что корень имеет индекс ноль, то есть используется массив с нулевой индексацией). Этот метод обеспечивает более компактное хранение и лучшую локальность ссылок, особенно при обходе в прямом порядке. Пространственная сложность этого метода составляет .

Применение

Одним из применений m-арного дерева является создание словаря для проверки допустимых строк. Для этого пусть m равно количеству допустимых символов (например, числу букв английского алфавита), при этом корень дерева представляет собой начальную точку. Аналогично, каждый узел может иметь до m дочерних узлов, представляющих следующий возможный символ в строке. Таким образом, символы вдоль путей могут представлять допустимые ключи, помечая конечный символ ключа как "терминальный узел". Например, в примере ниже "at" и "and" являются допустимыми ключевыми строками, где "t" и "d" помечены как терминальные узлы. Терминальные узлы могут хранить дополнительную информацию, связанную с данным ключом. Существуют схожие способы построения такого словаря с использованием B-деревьев, Octree и/или trie.