- Apter Trees en C++
- Un árbol representado de forma simple usando solo dos vectores: [valor del nodo, índice del padre)
- La mayoría de los árboles se implementan como árboles binarios, donde cada nodo incluye su valor y punteros a sus nodos hijo izquierdo/derecho
- Este tipo de estructura de datos suele requerir implementación recursiva y puede ser lenta por el comportamiento de caché y las llamadas frecuentes a
malloc()
- El concepto de quién "posee" un nodo del árbol puede volverse complejo en software de múltiples capas
- Los árboles Apter son mucho más rápidos, más fáciles de razonar y más fáciles de implementar
Cómo funciona
- Se implementa con dos arreglos del mismo tamaño
- Un vector (arreglo) de datos
d
- Un vector
p de índices de padre. El índice del vector d se usa como clave (c)
- A menudo la clave/índice
c es de tipo entero
- Si Coco es el padre de Molly y Arca, y Arca tiene un hijo llamado Cricket, la estructura queda así
tree.d = ["Coco", "Molly", "Arca","Cricket"]
tree.p = [0,0,0,2]
- El nodo cuyo padre es 0 y cuya clave es 0 es el nodo raíz (en los árboles Apter el nodo raíz es obligatorio, o bien
-1 significa "sin padre", pero aquí eso se omite)
- Las computadoras pueden manipular vectores muy rápido. Como esto es mucho más veloz que las operaciones con punteros, comparar la notación Big-O de los algoritmos en la práctica no tiene mucho sentido
Importancia
- Este estilo de implementación es el más elegante entre las implementaciones de árboles que el autor ha visto
- Si se usa una biblioteca adecuada de operaciones con vectores, es fácil de entender y de encontrar errores
- Por su simplicidad, puede adaptarse fácilmente a otros escenarios de uso
- Se puede iterar rápidamente sobre los valores ignorando el vector de índices de padre, lo que equivale a tener un Deep Map gratis
- Es amigable con GPU y fácil de usar en entornos embebidos
- La seguridad puede mantenerse fácilmente evitando que el tamaño de los vectores crezca más allá de cierto límite
Origen
- El autor está intentando encontrar a la persona que inventó esta técnica y supone que ya tenía nombre en la era orientada a vectores de los años 60 y 70
- Vio por primera vez una descripción completa tal como la explicó Apter, aunque también está ampliamente documentada en K3
- APL implementa árboles de la forma tradicional, pero usa una técnica similar para grafos vectoriales
- También es conocida entre usuarios de J, y existe una explicación sobre la implementación de árboles en J en Rosetta Code
- John Earnest explica con más detalle la implementación de árboles vectoriales, incluyendo el enfoque de "índice con desplazamiento" para manejar elementos eliminados
- Un enfoque más complejo consiste en rastrear la profundidad de cada elemento
Otras implementaciones comunes de árboles
- Existen implementaciones como el árbol del kernel de FreeBSD, los árboles de klib, la clase Tree de Ruby y clases de árboles declarativos en Python
- No realizan exactamente la misma función que los árboles Apter, y algunas son mucho más grandes debido a su generalización
Estado actual de este código
- Es un intento de implementarlo como ejercicio para aprender C++17
- Todavía no está listo para usarse y el autor necesita aprender más sobre C++
Opinión de GN⁺
- Apter Trees simplifica las estructuras de árbol complejas existentes y permite una gestión de datos rápida y eficiente
- La implementación de árboles basada en vectores minimiza la sobrecarga de memoria y puede mejorar el rendimiento mediante acceso lineal
- Este artículo resulta interesante para explorar enfoques innovadores de estructuras de datos en ingeniería de software
1 comentarios
Opiniones en Hacker News
mallocy mejorar la localidad de los datos.mallocpor la necesidad de agregar o quitar nodos dinámicamente. Mencionó que una implementación con arreglos puede ser adecuada si el tamaño del árbol es limitado y no se eliminan nodos con frecuencia.