Cada nodo del árbol puede tener un número arbitrario de hijos. Necesito una forma de construir y atravesar tales árboles, pero implementarlos usando un vector dimensional o una lista.Algoritmo para implementar árboles no binarios usando un vector de 1 dimensión?
Respuesta
Si sólo se puede utilizar un vector (no especificada en cuestión), y los nodos no debe contener su propia lista, sólo algunos indicadores (direcciones en el vector), entonces usted puede probar esto:
- cada nodo ejerce en la dirección de su hermano
- primer nodo después de dado (si no es su hermano) es niño, con el puntero al segundo hijo y así sucesivamente
- cada uno de sus hijos tiene sus propios hijos
así que para t ree así:
A
| \
B E ___
|\ \ \ \
C D F G H
su vector se vería así:
idx: 0 1 2 3 4 5 6 7
nodes: A B C D E F G H
next: _ 4 3 _ _ 6 7 _
donde _
es puntero nulo
Editar:
Otro enfoque:
- cada nodo tiene dirección de la región en el vector ocupada por sus hijos
- niños están uno junto al otro
- existe nodo nulo en el vector, el marcado final de los hermanos grupo
Para que el enfoque dado árbol se vería así:
idx: 0 1 2 3 4 5 6 7 8 9 A B
nodex: A _ B E _ C D _ F G H _
child: 2 5 8 _ _ _ _ _
De esta forma puede encontrar fácilmente hijos de cualquier nodo dado aleatoriamente y reorganizar una matriz sin mover todos los elementos (simplemente copie los elementos secundarios al final de la tabla, actualice el puntero y agregue el siguiente elemento al final de la tabla)
¿Eso no hace que E sea el hijo de D en su ejemplo, entonces? – danben
Y también de C [15 caracteres] – danben
@danben Solo si intenta atravesar desde cualquier nodo aleatorio. Si va desde la raíz (índice 0), entonces no debería ser posible. No es ideal, por lo que fue mi primera suposición después de ver esta pregunta – MBO
La forma estándar de almacenar un árbol binario completo en una matriz (como se usa para implementaciones de montón binario) es agradable porque puede representar el árbol con una matriz de elementos en el orden de un recorrido de árbol de orden de nivel. Usando ese esquema, hay trucos rápidos para calcular las posiciones del nodo padre e hijo. Pasar a un árbol en el que cada nodo puede tener un número arbitrario de elementos genera una llave en ese tipo de esquema.
Existen, sin embargo, varios esquemas para representar árboles arbitrarios como árboles binarios. Se discuten con gran detalle en el Arte de la Programación de Computadora de Donald Knuth, Volumen I, Sección 2.3.
Si los nodos en sí tienen permiso para contener un puntero, puede almacenar una lista de indicadores secundarios para cada nodo. ¿Es eso posible en tu caso?
Este problema sería mucho más fácil si los árboles fueran binarios. Pero tu respuesta se reduce a "Ve a leer Knuth", que no es tan útil. – danben
La parte útil de mi respuesta es notar que todos los árboles se pueden representar como árboles binarios, lo que no es necesariamente obvio, y proporcionar una fuente de esquemas para hacer eso. Hay muchos y que funcionarán mejor dependerá de los requisitos del OP. – PeterAllenWebb
"Ve a leer Knuth" es una respuesta a la mayoría de los problemas de la vida. Excepto tal vez las relaciones humanas. – Trevoke
Sin restricciones en los valores de los nodos, y suponiendo que sólo puede utilizar una única lista, me construir de la siguiente manera:
representar cada nodo como (val ; [ int ; ...])
donde val es el valor del nodo y cada int es el puesto en la lista de uno de sus hijos. Use un separador no imprimible si es necesario.
El recorrido es muy lento.
Puede implementarlo utilizando una lista vinculada unidimensional con poca sobrecarga.
Todos los padres contendrán punteros a sus hijos. (Pero esto requiere decidir si la cantidad máxima de nodos se conoce de antemano).
Para un árbol que tenga A como nodo raíz y B, C, D como hijos, su representación será la siguiente.
A -> B A -> C A -> D
Nota que hay 3 enlaces de A.
Una forma de superar el limite superior en el número de nodos está teniendo puntero adicional en los nodos
lo tanto, ahora A -> (niño) B -> (adj) -> (adj) C -> (adj) -> D
En este caso, es bastante compleja para actualizar el árbol, cuando eliminación ocurre.
Es aún más fácil diseñar mejores estructuras de datos si puede decir sus límites de tiempo en las diversas operaciones.
Lo que básicamente hace es escribir los inicios de un administrador de memoria para un intérprete Lisp emparejando los elementos del vector en celdas cons. Aquí hay una cosa tal Tiré juntos en C hace un momento:?
#include <stdbool.h>
#include <iso646.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define MEMORY_SIZE 1024
#define NIL 0
#define IVAL_MASK 0x8000000
struct pair
{
bool allocated;
size_t first;
size_t second;
};
size_t allocate_pair(struct pair vector[])
{
for (size_t i = 1; i < MEMORY_SIZE; i++)
{
if (not vector[i].allocated)
{
vector[i].allocated = true;
return i;
}
}
return NIL;
}
size_t make_pair(struct pair vector[], size_t a, size_t b)
{
size_t the_pair = allocate_pair(vector);
if (the_pair != NIL)
{
vector[the_pair].first = a;
vector[the_pair].second = b;
return the_pair;
}
else
{
fprintf(stderr,
"Out of pairs -- make_pair(%p, %zu, %zu)",
vector,
a,
b);
exit(EXIT_FAILURE);
}
}
size_t first(struct pair vector[], size_t index)
{
assert(vector[index].allocated);
return vector[index].first;
}
size_t second(struct pair vector[], size_t index)
{
assert(vector[index].allocated);
return vector[index].second;
}
void print_pair_aux(struct pair[], size_t, size_t);
void print_pair(struct pair vector[], size_t p)
{
assert(vector[p].allocated);
size_t a = first(vector, p);
size_t b = second(vector, p);
printf("(");
print_pair_aux(vector, a, b);
printf(")");
}
void print_pair_aux(struct pair vector[], size_t a, size_t b)
{
if (a == NIL)
printf("NIL");
else if (a >= IVAL_MASK)
printf("%zu", a &~ IVAL_MASK);
else
print_pair(vector, a);
if (b == NIL)
printf("");
else if (b >= IVAL_MASK)
printf(" . %zu", b &~ IVAL_MASK);
else
{
printf(" ");
print_pair_aux(vector,
first(vector, b),
second(vector, b));
}
}
int main(void)
{
struct pair *vector = calloc(MEMORY_SIZE, sizeof *vector);
#define cons(A,B) make_pair(vector, (A), (B))
#define ival(x) ((x) | IVAL_MASK)
size_t a = cons(ival(3), cons(ival(4), NIL));
size_t b = cons(ival(2), cons(a, NIL));
size_t c = cons(ival(6), cons(ival(7), cons(ival(8), NIL)));
size_t d = cons(ival(5), cons(c, NIL));
size_t e = cons(ival(1), cons(b, cons(d, NIL)));
print_pair(vector, e);
puts("");
}
$ cc -std=c99 try.c $ ./a.out (1 (2 (3 4)) (5 (6 7 8)))
- 1. OCaml: dibujar árboles binarios
- 2. JAVA: árboles binarios
- 3. C++ Para filtrar un vector de clase usando el algoritmo
- 4. Determine si dos árboles binarios son iguales
- 5. C# Árboles binarios y diccionarios
- 6. C++, implementando un iterador personalizado para árboles binarios (largo)
- 7. Algoritmo para dibujar árboles de manera eficiente
- 8. Algoritmo Divide-y-Conquista para árboles
- 9. árboles de búsqueda binarios en ruby
- 10. La matriz de 1 dimensión se cambia a un vector en R
- 11. Con 'N' no de nodos, ¿cuántos árboles de búsqueda binarios y binarios diferentes son posibles?
- 12. ¿Por qué son importantes los árboles binarios?
- 13. Cómo normalizar/desnormalizar un vector para oscilar [-1; 1]
- 14. Cómo puedo fusionar dos árboles binarios
- 15. Entender el algoritmo de Ukkonen para árboles de sufijo
- 16. imprimiendo todos los árboles binarios de inorder transversal
- 17. Algoritmo para implementar desplazamiento cinético
- 18. Regex para estructuras de árboles?
- 19. Cómo implementar: cambios de base de datos, fuente y binarios en 1 parche
- 20. Ejemplos concretos del uso de árboles de búsqueda binarios?
- 21. Transponer una matriz de 1 dimensión, que no representa un cuadrado, en su lugar
- 22. ISO 9797-1 Algoritmo 1 [CBC-MAC] en C#
- 23. Algoritmo de anidamiento 1-dimensional
- 24. ¿Cómo implementar un algoritmo tipo Digg?
- 25. Mejor estructura de datos para el vecino más cercano en 1 dimensión
- 26. Algoritmo de propósito general para triangular un gráfico no dirigido?
- 27. Algoritmo para implementar la declaración de rendimiento de C#
- 28. ¿Cómo crear un vector binario con 1 si los elementos son parte del mismo vector?
- 29. Convierta una matriz en una matriz de 1 dimensión
- 30. Diferencia de dos árboles de directorios para crear un parche de nivel de archivo/carpeta (incluidos los archivos binarios)
tarea ...... – Juliano
¿Hay alguna restricción en los valores de los nodos? – danben
@Juliano Ojalá .. Mis días de tarea se han ido :) @danben Sin restricción. – GabiMe