Árbol m-ario

En teoría de grafos, un árbol m-ario (para enteros no negativos m) (también conocido como n -ary, k-ary o árbol k-way) es un arborescencia (o, para algunos autores, un árbol ordenado) en el que cada nodo no tiene más de m hijos. Un árbol binario es el caso especial donde m = 2, y un árbol ternario es otro caso con m = 3 que limita sus hijos a tres.
Tipos de árboles m-arios
- A completo m- Árbol canario es un m- árbol diario donde dentro de cada nivel cada nodo tiene 0 o m niños.
- A completo m- Árbol canario (o, menos comúnmente, un perfecto m- Árbol canario) es un completo m- Árbol canario en el que todos los nudos de hoja están a la misma profundidad.
Propiedades de los árboles m-arios
- Para un m- Árbol con altura h, el límite superior para el número máximo de hojas es mh{displaystyle m^{h}.
- La altura h of an m- el árbol no incluye el nodo raíz, con un árbol que contiene sólo un nodo raíz que tiene una altura de 0.
- La altura de un árbol es igual a la profundidad máxima D de cualquier nodo en el árbol.
- El número total de nodos N{displaystyle N} en un perfecto m- El árbol es . . i=0hmi=mh+1− − 1m− − 1{textstyle sum ¿Qué? {m^{h+1}-1}{m-1}} {m}} {m}{h+1}}} {m}} {m} {m}} {m} {h} {h} {h}}}} {h} {h}}}}} {h+1}}}}}}} {h}}}}} {h}} {h}}}}}}}}}}}}}}}}}}}}}}}}} {h}}} {h}}}}}}}}}} {h} {h} {h} {h} {h} {h}} {h} {h} {h} {h}}}}}}}}}} {h}}}} {h}}}}}}} {h} {h} {h}}}}}}}} {h}}}}}}}}}}} {h}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} {h}}}}}}}, mientras la altura h es
- La altura de un completo m- Árbol canario con n nodos ⌊ ⌊ logm ()()m− − 1)⋅ ⋅ n)⌋ ⌋ {textstyle lfloor log _{m}(m-1)cdot n)rfloor }.
- El número total de posibles m- Árbol canario con n nodos Cn=1()m− − 1)n+1⋅ ⋅ ()m⋅ ⋅ nn){fnMicrosoftstyle C_{n}={frac {1}{(m-1)n+1}cdot {binom {mcdot No. (que es un número catalán).
Métodos de recorrido para árboles m-arios
Traversando un m- El árbol es muy similar a atravesar un árbol binario. El traversal pre-orden va a padres, subárbol izquierdo y subárbol derecho, y para atravesar post-orden va por subárbol izquierdo, subárbol derecho y nodo padre. Para atravesar en orden, ya que hay más de dos niños por nodo m 2, uno debe definir la noción de izquierda y derecho subárboles. Un método común para establecer subárboles izquierdo/derecho es dividir la lista de niños nodos en dos grupos. Al definir un orden sobre el m hijos de un nodo, el primero {}1,... ... ,⌊ ⌊ m2⌋ ⌋ }{textstyle {1,dotslfloor {fnMicroc {m}{2}rfloor} los nodos constituirían el subárbol izquierdo y {}⌈ ⌈ m2⌉ ⌉ ,... ... ,m}{textstyle {lceil {frac {m}{2}rceildotsm} los nodos constituirían el subárbol derecho.
Convertir un árbol m-ario en árbol binario

Usando un array para representar un m-ary tree is inefficient, because most of the nodes in practical applications contain less than m niños. Como resultado, este hecho conduce a una matriz espaciada con gran espacio no utilizado en la memoria. Convertir un arbitrario m-ary árbol a un árbol binario sólo aumentaría la altura del árbol por un factor constante y no afectaría la peor complejidad del tiempo. En otras palabras, O()logm n)↑ ↑ O()log2 n){textstyle O(log _{m}n)equiv O(log _{2}n)} desde entonces log2 m⋅ ⋅ logm n=log mlog 2⋅ ⋅ log nlog m=log2 n{textstyle log _{2}mcdot log ¿Qué?.
Primero, vinculamos todos los nodos secundarios inmediatos de un nodo principal determinado para formar una lista de vínculos. Luego, mantenemos el enlace del padre al primer hijo (es decir, el más a la izquierda) y eliminamos todos los demás enlaces al resto de los hijos. Repetimos este proceso para todos los hijos (si tienen hijos) hasta que hayamos procesado todos los nodos internos y giremos el árbol 45 grados en el sentido de las agujas del reloj. El árbol obtenido es el árbol binario deseado obtenido del árbol m-ario dado.
Métodos para almacenar árboles m-arios
Matrices

m- los árboles también se pueden almacenar en orden panorámico como una estructura de datos implícita en los arrays, y si el árbol es un completo m- Árbol, este método no desperdicia espacio. En este arreglo compacto, si un nodo tiene un índice i, su c- el niño en el rango {1,...m} se encuentra en el índice m⋅ ⋅ i+c{displaystyle mcdot i+c}, mientras que su padre (si alguno) se encuentra en el índice ⌊i− − 1m⌋{textstyle leftlfloor {frac Está bien. (Asumiendo que la raíz tiene índice cero, lo que significa un array basado en 0). Este método se beneficia de un almacenamiento más compacto y de una mejor localización de referencia, especialmente durante una transversal previa. La complejidad espacial de este método es O()mn){displaystyle O(m^{n}}.
Basado en puntero
Cada nodo tendría una matriz interna para almacenar punteros a cada uno de sus m{displaystyle m} niños:

En comparación con la aplicación basada en la matriz, este método de aplicación tiene una complejidad espacial superior O()m⋅ ⋅ n){displaystyle O(mcdot n)}.
Enumeración de árboles m-arios
Enumerar todos los árboles m-arios posibles es útil en muchas disciplinas como forma de comprobar hipótesis o teorías. La representación adecuada de los objetos del árbol m- puede simplificar enormemente el proceso de generación. Se puede construir una representación de secuencia de bits utilizando la búsqueda en profundidad de un árbol m-ario con n nodos que indican la presencia de un nodo en un índice dado utilizando valores binarios. Por ejemplo, la secuencia de bits x=1110000100010001000 representa un árbol tricario con n=6 nodos como se muestra a continuación.

El problema con esta representación es que enumerar todas las cadenas de bits en orden lexicográfico significaría dos cadenas sucesivas podrían representar dos árboles que son lexicográficamente muy diferentes. Por lo tanto, la enumeración sobre cadenas binarias no resultaría necesariamente en una generación ordenada de todos m-ary trees. Una mejor representación se basa en una cadena entero que indica el número de ceros entre sucesivos, conocidos como Simple Zero Sequence. S=s1,s2,... ... ,sn− − 1{fnMicrosoftstyle S=s_{1},s_{2},dotss_{n-1} es una secuencia Cero simple correspondiente a la secuencia de bits 10s110s2... ... 10sn− − 110j{fnMicrosoftstyle 10^{s_{1}10^{s_{2}ldots 10^{s_{n-1}10} {j} Donde j es el número de ceros necesarios en el extremo posterior de la secuencia para que la cadena tenga la longitud apropiada. Por ejemplo, 111000010001000↑ ↑ 100100104104103↑ ↑ 00433{displaystyle 111000010001000equiv 10^{0}10^{4}10^{4}10^{3}equiv 00433} es la simple representación de la secuencia cero de la figura anterior. Una representación más compacta 00433 es 024132{displaystyle 0^{2}4^{1}3^{2}, que se llama secuencia cero, que las bases duplicadas no pueden ser adyacentes. Esta nueva representación permite construir una próxima secuencia válida en O()1){displaystyle O(1)}. Una simple secuencia cero es válida si
La siguiente tabla muestra la lista de todas las secuencias cero simples válidas de todos los árboles 3-arios con 4 nodos:
| 222 | 200 | 111 | 033 | 013 |
| 221 | 132 | 110 | 032 | 012 |
| 220 | 131 | 105 | 031 | 011 |
| 213 | 130 | 104 | 030 | 010 |
| 212 | 123 | 103 | 024 | 006 |
| 211 | 122 | 102 | 023 | 005 |
| 210 | 121 | 101 | 022 | 004 |
| 204 | 120 | 100 | 021 | 003 |
| 203 | 114 | 042 | 020 | 002 |
| 202 | 113 | 041 | 015 | 001 |
| 201 | 112 | 040 | 014 | 000 |
A partir de la parte inferior derecha de la tabla (es decir, "000"), hay una plantilla troncal que gobierna la generación de los posibles árboles ordenados a partir de " ;000" a "006". La plantilla principal para este grupo ("00X") se muestra a continuación, donde se agrega un nodo adicional en las posiciones etiquetadas como "x".

Una vez que se hayan agotado todas las posiciones posibles en la plantilla de la red troncal, se construirá una nueva plantilla desplazando el tercer nodo una posición hacia la derecha como se muestra a continuación, y se producirá la misma enumeración hasta que todas las posiciones posibles etiquetadas como " X" está agotado.

Volver a la tabla de enumeración de todos m- árboles cansados, donde m=3{displaystyle m=3} y n=4{displaystyle n=4}, podemos observar fácilmente el salto aparente de "006" a "010" se puede explicar trivialmente en una forma algorítmica como se describe a continuación:

El pseudocódigo para esta enumeración se proporciona a continuación:
Procedimiento NEXT(s1, s2, ... sn−1)
si si = 0 para todos i entoncesacabado
más i ← max {i Silencio si ■ 0}
si ← si − 1
si i c) n − 1 entonces si ←i + 1) ⋅ (m −1) − sum(sj)
terminar si para j ← i + 2, i + 3, ..., n − 1
sj ← k − 1
terminar sifinalEnumeración sin bucles
Un algoritmo de generación que toma O()1){displaystyle O(1)} El peor de los casos se llama inigualable, ya que la complejidad del tiempo no puede implicar un bucle o recursión. enumeración sin límites de m-ary trees is said to be loopless if after initialization, it generates successive tree objects in O()1){displaystyle O(1)}. Para un dado m-ary tree T con a{displaystyle a} ser uno de sus nodos y d{displaystyle d} su t{displaystyle t}- niño, un rotación izquierda-t a a{displaystyle a} se hace haciendo d{displaystyle d} el nodo raíz, y haciendo b{displaystyle b} y todos sus subárboles un niño de a{displaystyle a}, además asignamos el m− − 1{displaystyle m-1} la mayoría de los niños d{displaystyle d} a a{displaystyle a} y el niño más adecuado d{displaystyle d} permanece unida a ella mientras d{displaystyle d} se promueve a raíz, como se muestra a continuación:

Convertir un árbol m-ary en árbol izquierdo para i = 1...n: para t = 2...m: mientras t niño de nodo a fondo i ه 1: rotación en los nodos a profundidad i terminar mientras final for final for
A rotación derecha-t a d es el inverso de esta operación. El cadena izquierda de T es una secuencia de x1,x2,... ... ,xn{displaystyle x_{1},x_{2},dotsx_{n} nodos tales que x1{displaystyle x_{1}} es la raíz y todos los nodos excepto xn{displaystyle x_{n} tener un niño conectado a la izquierda más (es decir, m[1]{displaystyle m[1]}El puntero. Cualquier m-ary árbol se puede transformar a cadena izquierda árbol usando secuencia de finito rotaciones izquierda-t para t desde 2 a m. Específicamente, esto se puede hacer ejecutando rotaciones izquierda-t en cada nodo xi{displaystyle x_{i}} hasta todo su m− − 1{displaystyle m-1} sub-árbol nulo a cada profundidad. Luego, la secuencia del número de rotaciones izquierda-t realizadas a profundidad i denotado por ci{displaystyle C_{i} define a code of a m-árbol de ary que se puede recuperar realizando la misma secuencia de rotacións derecha-t.
Deja que m− − 1{displaystyle m-1} tuple of c1,c2,... ... ,cm− − 1{displaystyle c_{1},c_{2},dotsc_{m-1} representan el número de L-2 rotaciones, L-3 rotaciones,... L-m rotaciones que se han producido en la raíz (es decir, i=1). Entonces, c()i− − 1)()m− − 1)+t− − 1{displaystyle c_{(i-1)(m-1)+t-1} es el número de L-t rotación necesaria a profundidad i.
Capturing counts of left-rotations at each deep is a way of encoding an m- Árbol. Así, enumerar toda posible codificación legal nos ayudaría a generar todo el m-Arboles canarios para un m y n. Pero no todo ci{displaystyle C_{i} secuencias de m Los enteros no negativos representan un árbol m-ary válido. Una secuencia de ()n− − 1)⋅ ⋅ ()m− − 1)+1{displaystyle (n-1)cdot (m-1)+1} Los enteros no negativos es una representación válida de un m-ary árbol si y sólo si
Lexicographically smallest code-word representation of a m-ary con n los nodos son todos ceros y el mayor es n−1 seguidos m−1 cero a su derecha.
Iniciaciónc[i] a cero para todos yo de 1 a 1 n⋅(k −1) p[i] n − 1 para mí de 1 a n suma ← 0 j ← m − 1 Estado de terminaciónTerminar cuando c[1] = n − 1 Procedimiento NEXT suma ← suma + 1 - c[j + 1] c[j] ← c[j+ 1 si p[q[j]] p[q[j + 1] + 1 entonces p[q[j← p[q[j + 1] + 1 terminar si p[q[j + c[j]] p[q[j]] c[j + 1] ← 0 si suma = p[q[j]] entonces j ← j − 1 más p[n← suma j ← m − 1 terminar sifinal
Aplicación
Una de las aplicaciones del árbol m-ary es la creación de un diccionario para la validación de cadenas aceptables. Para hacer eso, sea m igual al número de alfabetos válidos (por ejemplo, el número de letras del alfabeto inglés) y la raíz del árbol representa el punto de partida. De manera similar, cada uno de los hijos puede tener hasta m hijos que representen el siguiente carácter posible en la cadena. Por lo tanto, los caracteres a lo largo de las rutas pueden representar claves válidas marcando el carácter final de las claves como "nodo terminal". Por ejemplo, en el siguiente ejemplo "en" y "y" son cadenas de claves válidas con "t" y "d" marcados como nodos terminales. Los nodos terminales pueden almacenar información adicional para asociarla con una clave determinada. Hay formas similares de crear un diccionario de este tipo utilizando B-tree, Octree y/o trie.
