¿Por qué utilizar el árbol de búsqueda ternario en lugar de reemplazar cada nodo de Trie a un árbol BST?

La respuesta corta es que a veces las constantes son importantes.

Desde un punto de vista asintótico, todas las variaciones de trie tienen aproximadamente el mismo rendimiento: la cantidad de espacio consumido es lineal en la longitud total de las palabras almacenadas, y el tiempo necesario para insertar / buscar una palabra es lineal en su longitud.

Sin embargo, también hay otro parámetro que a veces es importante: el tamaño de su alfabeto. Aunque el tamaño del alfabeto es a menudo una constante, existe una diferencia entre las constantes 2 (sus caracteres son 0 y 1), 4 (CGAT) y 95 (ASCII imprimible de 7 bits). Además, hay algunas situaciones muy específicas en las que el tamaño del alfabeto es realmente proporcional a la longitud total de la entrada. Por lo tanto, tiene sentido considerar el tamaño del alfabeto (sigma) como una segunda variable al analizar la complejidad temporal y espacial de los intentos.

Por ejemplo, en su búsqueda básica, el tiempo de búsqueda no depende del tamaño del alfabeto, pero la complejidad del espacio sí: en realidad es la longitud total de todas las palabras por el tamaño del alfabeto, porque cada nodo almacena punteros O (sigma).

Muchos usos de los intentos están en entornos donde el consumo de memoria es el cuello de botella. La búsqueda es lo suficientemente rápida por un amplio margen, por lo que puede optar por una compensación: ralentice la búsqueda ligeramente pero ahorre mucha memoria. En algunos casos (p. Ej., Cuando esto ayuda a ajustar todo su trie en su RAM), esta compensación puede incluso conducir a un mejor rendimiento práctico.

Probablemente la forma más extrema de hacer esta compensación es la representación del niño izquierdo / hermano derecho (LCRS). En este trie, cada nodo solo almacena dos bordes salientes en lugar de sigma. Por ejemplo, si su vainilla contiene un nodo A con hijos B, C, D, E, en esta representación, el puntero hijo izquierdo de A apunta a B, el puntero hermano derecho de B apunta a C, el hermano derecho de C es D, y así sucesivamente.

En estos árboles, la búsqueda se reduce a O (sigma * longitud de palabra), pero la complejidad del espacio ya no depende de sigma.

Los intentos de búsqueda ternaria van más allá de este espectro de compensación: pueden ser un poco más rápidos, pero su consumo de memoria es ligeramente mayor. (Más precisamente, la complejidad del espacio aún no depende de sigma, el peor caso de búsqueda es el mismo que en los intentos de LCRS, pero el caso promedio de búsqueda es O (log sigma * longitud de palabra) si las palabras se insertaron en orden aleatorio, y esto incluso puede convertirse en el peor de los casos si el trie es estático).

Su propuesta es almacenar un BST equilibrado de enlaces secundarios en cada nodo del trie. Esto está aún más abajo en la línea. El consumo de memoria aún no depende de sigma, pero está desperdiciando más memoria que en las soluciones anteriores: el factor constante es peor porque cada BST tiene un montón de punteros NULL adicionales. Las búsquedas serán buenas, aproximadamente tan rápido como en un trie de búsqueda ternario construido de manera óptima, pero las inserciones pueden ser más lentas en la práctica: la sobrecarga de equilibrar un nodo puede ser fácilmente más que el tiempo necesario para encontrar y modificar el lugar correcto simplemente siguiendo algunos consejos y luego cambiándolos localmente en tiempo constante. Realmente no puedo imaginar una situación en la que esta implementación particular sería deseable.

Además, para la mayoría de los usos de los intentos, el orden de los nodos secundarios en realidad no importa, y es mejor usar una pequeña tabla hash en lugar del BST.

De todos modos, el propósito de todas estas variaciones es tener una opción. Analice su situación, descubra cuáles son los cuellos de botella y elija en consecuencia.

More Interesting

¿Cuál es el algoritmo utilizado por Diffbot para extraer datos web?

¿Las estructuras de datos y los algoritmos son tan importantes para convertirse en un buen programador?

¿Debo comenzar a aprender estructuras de datos y algoritmos en lugar de nuevos lenguajes de programación?

¿Alguien puede ayudarme a dibujar un árbol de recursión para la ecuación [matemáticas] T (n) = T (n-2) + n [/ matemáticas]?

¿Existe un algoritmo para generar todas las combinaciones de manera ordenada?

¿Qué nivel / conocimiento de programación debería tener para obtener el máximo provecho de CLRS? [Más detalles en mi respuesta contraída]

Cómo hacer un algoritmo de filtrado basado en contenido de Python

¿Cuál es el proceso de ejecución exacto de imprimir permutaciones de cadena de forma recursiva?

¿Dónde puedo encontrar una comprensión realmente fácil y rápida de todas las estructuras de datos y algoritmos?

¿Deben las clases de algoritmos incluir tareas de programación?

¿Qué opina sobre la preferencia del algoritmo de alimentación de Quora para distribuir contenido más nuevo?

En problemas de DP, ¿cómo sabe si usar una matriz / tabla 1D o una matriz / tabla 2D?

¿Se puede implementar la imaginación usando algoritmos? ¿Hay algo que no podamos explicar a través de un algoritmo, incluso en el futuro?

Cómo evaluar el efecto del programa de seguridad vial en el comportamiento después de 7 años de implementación si no hay datos de referencia

¿Por qué debería aprender algoritmos antes de entrar en la programación?