В теории графов m - арное дерево (для неотрицательных целых чисел m ) (также известное как n -арное , k -арное или k -путевое дерево) — это древовидное дерево (или, по мнению некоторых авторов, упорядоченное дерево ) [1] [2] , в котором каждый узел имеет не более m потомков. Бинарное дерево — важный случай, когда m = 2; аналогично, тернарное дерево — это дерево, где m = 3.
По определению Big-Ω максимальная глубина
Обход m -арного дерева очень похож на обход бинарного дерева. Прямой обход идет к родительскому, левому поддереву и правому поддереву, а для обратного обхода он идет по левому поддереву, правому поддереву и родительскому узлу. Для обхода в порядке, поскольку на узел приходится более двух потомков при m > 2 , необходимо определить понятия левого и правого поддеревьев. Один из распространенных методов установления левых/правых поддеревьев — разделить список дочерних узлов на две группы. Определив порядок для m потомков узла, первые узлы составят левое поддерево, а узлы составят правое поддерево.
Использование массива для представления m- арного дерева неэффективно, поскольку большинство узлов в практических приложениях содержат менее m потомков. В результате этот факт приводит к разреженному массиву с большим неиспользуемым пространством в памяти. Преобразование произвольного m- арного дерева в двоичное дерево увеличит высоту дерева только на постоянный множитель и не повлияет на общую временную сложность в худшем случае. Другими словами, поскольку .
Сначала мы связываем все непосредственные дочерние узлы данного родительского узла вместе, чтобы сформировать список ссылок. Затем мы сохраняем ссылку от родителя к первому (то есть самому левому) дочернему узлу и удаляем все остальные ссылки к остальным дочерним узлам. Мы повторяем этот процесс для всех дочерних узлов (если у них есть дочерние узлы), пока не обработаем все внутренние узлы и не повернем дерево на 45 градусов по часовой стрелке. Полученное дерево является желаемым бинарным деревом, полученным из данного m -арного дерева.
m -арные деревья также могут храниться в порядке "в ширину" как неявная структура данных в массивах , и если дерево является полным m -арным деревом, этот метод не тратит место впустую. В этом компактном расположении, если узел имеет индекс i , его c -ый потомок в диапазоне {1,…, m } находится по индексу , в то время как его родитель (если таковой имеется) находится по индексу (предполагая, что корень имеет нулевой индекс, что означает массив с нулевым индексом). Этот метод выигрывает от более компактного хранения и лучшей локальности ссылок , особенно во время обхода в прямом порядке. Пространственная сложность этого метода составляет .
Каждый узел будет иметь внутренний массив для хранения указателей на каждого из своих дочерних узлов:
По сравнению с реализацией на основе массива этот метод реализации имеет превосходящую пространственную сложность .
Перечисление всех возможных m -арных деревьев полезно во многих дисциплинах как способ проверки гипотез или теорий. Правильное представление объектов m- арного дерева может значительно упростить процесс генерации. Можно построить представление битовой последовательности , используя поиск в глубину m -арного дерева с n узлами, указывающими на наличие узла с заданным индексом, используя двоичные значения. Например, битовая последовательность x=1110000100010001000 представляет собой 3-арное дерево с n=6 узлами, как показано ниже.
Проблема с этим представлением заключается в том, что перечисление всех строк битов в лексикографическом порядке означало бы, что две последовательные строки могут представлять два дерева, которые лексикографически сильно различаются. Поэтому перечисление по двоичным строкам не обязательно приведет к упорядоченной генерации всех m- арных деревьев. [7] Лучшее представление основано на целочисленной строке, которая указывает количество нулей между последовательными единицами, известной как простая нулевая последовательность . — это простая нулевая последовательность, соответствующая битовой последовательности , где j — это количество нулей, необходимых в конце последовательности, чтобы строка имела соответствующую длину. Например, — это простое представление нулевой последовательности на рисунке выше. Более компактным представлением 00433 является , которое называется нулевой последовательностью , в которой дублирующиеся основания не могут быть смежными. Это новое представление позволяет построить следующую допустимую последовательность в . Простая нулевая последовательность допустима, если То есть количество нулей в битовой последовательности m -арного дерева не может превышать общего количества нулевых указателей (т. е. указателей без прикрепленных к ним дочерних узлов). Это суммирование накладывает ограничение на узлы, чтобы было место для добавления без создания недействительной структуры (т.е. имея доступный нулевой указатель для присоединения к нему последнего узла).
В таблице ниже представлен список всех допустимых простых нулевых последовательностей всех 3 -арных деревьев с 4 узлами:
Начиная с нижнего правого угла таблицы (т. е. "000"), есть шаблон основы , который управляет генерацией возможных упорядоченных деревьев, начиная с "000" до "006". Шаблон основы для этой группы ("00X") изображен ниже, где дополнительный узел добавляется в позиции, обозначенные "x".
После того, как все возможные позиции в шаблоне основы будут исчерпаны, будет создан новый шаблон путем смещения третьего узла на одну позицию вправо, как показано ниже, и тот же самый подсчет будет выполняться до тех пор, пока все возможные позиции, помеченные «X», не будут исчерпаны.
Возвращаясь к таблице перечисления всех m -арных деревьев, где и , мы можем легко заметить, что кажущийся скачок от «006» до «010» можно объяснить тривиально в алгоритмической форме, как показано ниже:
Псевдокод для этого перечисления приведен ниже: [7]
Процедура NEXT( s 1 , s 2 , …, s n −1 ) если s i = 0 для всех i то законченный else i ← max { i | s i > 0} s i ← s i − 1 if i < n − 1 then s i ← ( i + 1) ⋅ ( m − 1) − sum( s j ) end if for j ← i + 2, i + 3, …, n − 1 s j ← k − 1 end if end
Алгоритм генерации, который занимает наихудшее время, называется бесцикловым, поскольку временная сложность не может включать цикл или рекурсию. Бесцикловое перечисление m- арных деревьев называется бесцикловым, если после инициализации оно генерирует последовательные объекты деревьев в . Для заданного m -арного дерева T, являющегося одним из его узлов и его -го потомка, поворот налево-t в выполняется путем создания корневого узла и превращения и всех его поддеревьев в потомков , дополнительно мы назначаем самых левых потомков , а самый правый потомок остается прикрепленным к нему, пока повышается до корня, как показано ниже:
Преобразовать m-арное дерево в левое дерево для i = 1... n : для t = 2... m : пока t является потомком узла на глубине i ≠ 1: Вращение Lt в узлах на глубине i заканчивается, пока конец для конца для
Вращение вправо-t в точке d является обратной операцией. Левая цепочка T представляет собой последовательность узлов, таких что является корнем, и все узлы, за исключением , имеют одного потомка, соединенного с их самым левым (т. е. ) указателем. Любое m- арное дерево может быть преобразовано в дерево левой цепи с помощью последовательности конечных вращений влево-t для t от 2 до m . В частности, это можно сделать, выполняя вращения влево-t на каждом узле , пока все его поддерево не станут нулевыми на каждой глубине. Затем последовательность числа вращений влево-t, выполненных на глубине i, обозначенная как , определяет кодовое слово m - арного дерева, которое можно восстановить, выполнив ту же последовательность вращений вправо-t.
Пусть кортеж представляет собой число вращений L-2 , вращений L-3 , ..., вращений Lm , которые произошли в корне (т.е. i = 1). Тогда — число вращений Lt , требуемых на глубине i .
Сбор количества левых поворотов на каждой глубине является способом кодирования m -арного дерева. Таким образом, перечисление всех возможных допустимых кодировок поможет нам сгенерировать все m -арные деревья для заданных m и n . Но не все последовательности из m неотрицательных целых чисел представляют собой допустимое m-арное дерево. Последовательность неотрицательных целых чисел является допустимым представлением m - арного дерева тогда и только тогда, когда [8]
Лексикографически наименьшее кодовое слово, представляющее m-арную последовательность с n узлами, состоит из одних нулей, а наибольшее — из n −1 единиц, за которыми справа следует m −1 нулей.
Инициализация c[i] в ноль для всех i от 1 до n ⋅( k − 1) p[i] установлено в n − 1 для i от 1 до n сумма ← 0 j ← m − 1Условие завершения Завершить, когда c[1] = n − 1Процедура NEXT [8] сумма ← сумма + 1 − c [ j + 1] c [j] ← c [ j ] + 1 если p [ q [ j ]] > p [ q [ j + 1]] + 1 тогда p [ q [ j ]] ← p [ q [ j + 1]] + 1 конец если p [ q [ j + c [ j ]]] ← p [ q [ j ]] c [ j + 1] ← 0 если сумма = p [ q [ j ]] тогда j ← j − 1 иначе p [ n ] ← сумма j ← m − 1 конец если конец
Одним из применений m -арного дерева является создание словаря для проверки допустимых строк. Чтобы сделать это, пусть m будет равно количеству допустимых алфавитов (например, количеству букв английского алфавита ), а корень дерева будет представлять начальную точку. Аналогично, каждый из потомков может иметь до m потомков, представляющих следующий возможный символ в строке. Таким образом, символы вдоль путей могут представлять допустимые ключи, помечая конечный символ ключей как «конечный узел». Например, в примере ниже «at» и «and» являются допустимыми ключевыми строками, а «t» и «d» отмечены как конечные узлы. Конечные узлы могут хранить дополнительную информацию, которая будет связана с данным ключом. Существуют похожие способы построения такого словаря с использованием B-дерева , октадерева и/или trie .
{{cite book}}
: CS1 maint: location (link){{cite book}}
: CS1 maint: location (link){{cite book}}
: CS1 maint: location (link)