En teoría de grafos , un árbol m -ario (para números enteros no negativos m ) (también conocido como n -ario , k -ario o árbol k -via ) es una arborescencia (o, para algunos autores, un árbol ordenado ) [1] [2] en el que cada nodo no tiene más de m hijos. Un árbol binario es un caso importante donde m = 2; de manera similar, un árbol ternario es uno donde m = 3.
Según la definición de Big-Ω, la profundidad máxima
Recorrer un árbol m -ario es muy similar a recorrer un árbol binario. El recorrido en preorden va al padre, al subárbol izquierdo y al subárbol derecho, y para recorrer en posorden va por el subárbol izquierdo, el subárbol derecho y el nodo padre. Para recorrer en orden, dado que hay más de dos hijos por nodo para m > 2 , se debe definir la noción de subárboles izquierdo y derecho . Un método común para establecer subárboles izquierdo/derecho es dividir la lista de nodos hijos en dos grupos. Al definir un orden en los m hijos de un nodo, los primeros nodos constituirían el subárbol izquierdo y los nodos constituirían el subárbol derecho.
El uso de una matriz para representar un árbol m -ario es ineficiente, porque la mayoría de los nodos en aplicaciones prácticas contienen menos de m hijos. Como resultado, este hecho conduce a una matriz dispersa con un gran espacio sin usar en la memoria. Convertir un árbol m- ario arbitrario en un árbol binario solo aumentaría la altura del árbol por un factor constante y no afectaría la complejidad temporal general del peor caso. En otras palabras, dado que .
Primero, vinculamos todos los nodos hijos inmediatos de un nodo padre dado para formar una lista de enlaces. 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 hayamos rotado el árbol 45 grados en el sentido de las agujas del reloj. El árbol obtenido es el árbol binario deseado obtenido a partir del árbol m -ario dado.
Los árboles m -arios también se pueden almacenar en orden de amplitud como una estructura de datos implícita en matrices y, si el árbol es un árbol m -ario completo, este método no desperdicia espacio. En esta disposición compacta, si un nodo tiene un índice i , su c -ésimo hijo en el rango {1,…, m } se encuentra en el índice , mientras que su padre (si lo hay) se encuentra en el índice (asumiendo que la raíz tiene índice cero, es decir, una matriz basada en 0). Este método se beneficia de un almacenamiento más compacto y una mejor localidad de referencia , particularmente durante un recorrido de preorden. La complejidad espacial de este método es .
Cada nodo tendría una matriz interna para almacenar punteros a cada uno de sus hijos:
En comparación con la implementación basada en matrices, este método de implementación tiene una complejidad espacial superior de .
Enumerar todos los árboles m -arios posibles es útil en muchas disciplinas como una forma de comprobar hipótesis o teorías. La representación adecuada de los objetos de árboles m- arios puede simplificar en gran medida 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 indique la presencia de un nodo en un índice dado utilizando valores binarios. Por ejemplo, la secuencia de bits x=1110000100010001000 representa un árbol 3-ario con n=6 nodos como se muestra a continuación.
El problema con esta representación es que listar todas las cadenas de bits en orden lexicográfico significaría que dos cadenas sucesivas podrían representar dos árboles que son lexicográficamente muy diferentes. Por lo tanto, la enumeración sobre cadenas binarias no necesariamente resultaría en una generación ordenada de todos los árboles m- arios. [7] Una mejor representación se basa en una cadena entera que indica el número de ceros entre unos sucesivos, conocida como Secuencia Cero Simple . es una Secuencia Cero Simple que corresponde a la secuencia de bits donde j es el número de ceros necesarios al final de la secuencia para hacer que la cadena tenga la longitud apropiada. Por ejemplo, es la representación de secuencia cero simple de la figura anterior. Una representación más compacta de 00433 es , que se llama secuencia cero , cuyas bases duplicadas no pueden ser adyacentes. Esta nueva representación permite construir una siguiente secuencia válida en . Una secuencia cero simple es válida si Es decir que el número de ceros en la secuencia de bits de un árbol m -ario no puede exceder el número total de punteros nulos (es decir, punteros sin ningún nodo hijo adjunto a ellos). Esta suma pone restricciones en los nodos para que haya espacio para agregarlos sin crear una estructura no válida (es decir, tener un puntero nulo disponible para adjuntarle el último nodo).
La siguiente tabla muestra la lista de todas las secuencias cero simples válidas de todos los árboles 3 -arios con 4 nodos:
A partir de la parte inferior derecha de la tabla (es decir, "000"), hay una plantilla de estructura principal que rige la generación de los posibles árboles ordenados desde "000" hasta "006". La plantilla de estructura 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 realizará la misma enumeración hasta que se agoten todas las posiciones posibles etiquetadas como "X".
Volviendo a la tabla de enumeración de todos los árboles m -arios, donde y , podemos observar fácilmente que el salto aparente de "006" a "010" se puede explicar trivialmente de manera algorítmica como se muestra a continuación:
El pseudocódigo para esta enumeración se proporciona a continuación: [7]
Procedimiento NEXT( s 1 , s 2 , …, s n −1 ) si s i = 0 para todo i entonces finalizado de lo contrario i ← máx { i | s i > 0} s i ← s i − 1 si i < n − 1 entonces s i ← ( i + 1) ⋅ ( m − 1) − suma( s j ) fin si para j ← i + 2, i + 3, …, n − 1 s j ← k − 1 fin si fin
Un algoritmo de generación que toma el peor tiempo posible se denomina sin bucles, ya que la complejidad temporal no puede implicar un bucle o una recursión. Se dice que la enumeración sin bucles de árboles m -arios no tiene bucles si, después de la inicialización, genera objetos de árbol sucesivos en . Para un árbol m- ario T dado , donde uno de sus nodos y su hijo -ésimo, se realiza una rotación a la izquierda en t haciendo que el nodo raíz y todos sus subárboles sean hijos de , además, asignamos los hijos más a la izquierda de a y el hijo más a la derecha de permanece adjunto a él mientras se promueve a raíz, como se muestra a continuación:
Convertir un árbol m-ario en un árbol izquierdo para i = 1... n : para t = 2... m : mientras t sea hijo del nodo en la profundidad i ≠ 1: Rotación de Lt en nodos a profundidad i fin mientras fin para fin para
Una rotación t-derecha en d es la inversa de esta operación. La cadena izquierda de T es una secuencia de nodos tal que es la raíz y todos los nodos excepto tienen un hijo conectado a su puntero más a la izquierda (es decir, ). Cualquier árbol m- ario se puede transformar en un árbol de cadena izquierda utilizando una secuencia de rotaciones t-izquierdas finitas para t desde 2 hasta m . Específicamente, esto se puede hacer realizando rotaciones t-izquierdas en cada nodo hasta que todos sus subárboles se vuelvan nulos en cada profundidad. Luego, la secuencia del número de rotaciones t-izquierdas realizadas en la profundidad i denotada por define una palabra de código de un árbol m- ario que se puede recuperar realizando la misma secuencia de rotaciones t-derechas.
Sea la tupla de la que representa el número de rotaciones L-2 , rotaciones L-3 , ..., Lm que han ocurrido en la raíz (es decir, i = 1). Entonces, es el número de rotaciones Lt requeridas a la profundidad i .
Capturar los recuentos de rotaciones a la izquierda en cada profundidad es una forma de codificar un árbol m -ario. Por lo tanto, enumerar todas las codificaciones legales posibles nos ayudaría a generar todos los árboles m -arios para un m y n dados . Pero no todas las secuencias de m números enteros no negativos representan un árbol m-ario válido. Una secuencia de números enteros no negativos es una representación válida de un árbol m -ario si y solo si [8]
La representación lexicográficamente más pequeña de una palabra código de un m-ario con n nodos es toda ceros y la más grande es n −1 unos seguidos de m −1 ceros a su derecha.
Inicialización c[i] a cero para todos los i desde 1 hasta n ⋅( k − 1) p[i] establecido en n − 1 para i de 1 a n suma ← 0 j ← m − 1Condición de terminación Terminar cuando c[1] = n − 1Procedimiento SIGUIENTE [8] 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 fin si p [ q [ j + c [ j ]]] ← p [ q [ j ]] c [ j + 1] ← 0 si suma = p [ q [ j ]] entonces j ← j − 1 de lo contrario p [ n ] ← suma j ← m − 1 fin si fin
Una de las aplicaciones del árbol m -ario es la creación de un diccionario para la validación de cadenas aceptables. Para ello, sea m igual al número de alfabetos válidos (por ejemplo, el número de letras del alfabeto inglés ) con la raíz del árbol representando el punto de partida. De forma similar, cada uno de los hijos puede tener hasta m hijos que representan 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 ejemplo siguiente "at" y "and" 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 dada. Existen formas similares de construir un diccionario de este tipo utilizando B-tree , Octree y/o trie .
{{cite book}}
: CS1 maint: location (link){{cite book}}
: CS1 maint: location (link){{cite book}}
: CS1 maint: location (link)