Un montón sesgado (o montón autoajustable ) es una estructura de datos de montón implementada como un árbol binario . Los montones sesgados son ventajosos debido a su capacidad para fusionarse más rápidamente que los montones binarios. A diferencia de los montones binarios , no hay restricciones estructurales, por lo que no hay garantía de que la altura del árbol sea logarítmica. Solo se deben cumplir dos condiciones:
Un montón sesgado es una forma autoajustable de un montón izquierdista que intenta mantener el equilibrio intercambiando incondicionalmente todos los nodos en la ruta de fusión al fusionar dos montones. (La operación de combinación también se usa al agregar y eliminar valores). Sin restricciones estructurales, puede parecer que un montón sesgado sería terriblemente ineficaz. Sin embargo, el análisis de complejidad amortizada se puede utilizar para demostrar que todas las operaciones en un montón sesgado se pueden realizar en O (log n ). [1] De hecho, al denotar la proporción áurea , se sabe que la complejidad amortizada exacta es log φ n (aproximadamente 1,44 log 2 n ). [2] [3]
Los montones sesgados se pueden describir con la siguiente definición recursiva : [ cita requerida ]
Cuando se van a fusionar dos montones sesgados, podemos usar un proceso similar al de la fusión de dos montones de izquierda :
plantilla < clase T , clase CompareFunction > SkewNode < T > * CSkewHeap < T , CompareFunction > :: _Merge ( SkewNode < T > * root_1 , SkewNode < T > * root_2 ) { SkewNode < T > * firstRoot = root_1 ; SkewNode < T > * secondRoot = root_2 ; si ( firstRoot == NULL ) return secondRoot ; else if ( secondRoot == NULL ) return firstRoot ; if ( sh_compare -> Less ( firstRoot -> clave , secondRoot -> clave )) { SkewNode < T > * tempHeap = firstRoot -> rightNode ; firstRoot -> rightNode = firstRoot -> leftNode ; firstRoot -> leftNode = _Merge ( secondRoot , tempHeap ); return firstRoot ; } demás return _Merge ( secondRoot , firstRoot ); }
Alternativamente, existe un enfoque no recursivo que es más prolijo y requiere alguna clasificación desde el principio.
Agregar un valor a un montón sesgado es como fusionar un árbol con un nodo junto con el árbol original.
La eliminación del primer valor de un montón se puede lograr eliminando la raíz y fusionando sus subárboles secundarios.
En muchos lenguajes funcionales, los montones de sesgos se vuelven extremadamente simples de implementar. Aquí hay una implementación de muestra completa en Haskell.
datos SkewHeap a = Vacío | Nodo a ( SkewHeap a ) ( SkewHeap a )singleton :: Ord a => a -> SkewHeap a singleton x = Nodo x Vacío VacíoUnión :: Ord un => SkewHeap un -> SkewHeap un -> SkewHeap un vacío ` unión ` t2 = t2 t1 ` unión ` Vaciar = t1 t1 @ ( Nodo x1 L1 r1 ) ` unión ` t2 @ ( Nodo x2 l2 r2 ) | x1 <= x2 = Nodo x1 ( t2 ` Unión ` r1 ) l1 | de lo contrario = Nodo x2 ( t1 ` unión ` r2 ) l2inserte :: Ord un => una -> SkewHeap un -> SkewHeap un inserto x montón = Singleton x ` unión ` montónextractMin :: Ord un => SkewHeap un -> Tal vez ( una , SkewHeap una ) extractMin Vacía = Nada extractMin ( Nodo x l r ) = Justo ( x , l ` unión ` r )