Pero se trata de crear un nuevo conjunto n veces. ¿Hay alguna manera de hacerlo y solo crear un nuevo conjunto una vez?
Según mi leal saber y entender, no. Diría que tiene una implementación perfectamente correcta, se ejecuta en O (lg n) y también es concisa :) La mayoría de las implementaciones de montón le dan O (lg n) para eliminar min de todos modos, entonces lo que tiene se trata de tan bueno como puedas conseguirlo.
Es posible que pueda obtener un poco mejor velocidad rodando su árbol equilibrado, y la implementación de una función para colocar una rama izquierda o derecha para todos los valores superiores a un cierto valor. No creo que un árbol AVL o RB sea apropiado en este contexto, ya que no puedes mantener sus invariantes, pero un árbol con asignación aleatoria te dará los resultados que deseas.
Una corrección funciona de maravilla para esto, porque usa aleatorización en lugar de invariantes de árbol para mantenerse relativamente equilibrado. A diferencia de un árbol AVL o un árbol RB, puede dividir un ataque en un nodo sin preocuparse de que esté desequilibrado.He aquí una aplicación Treap que escribí hace unos meses:
http://pastebin.com/j0aV3DJQ
He añadido una función split
, lo que le permite tener un árbol y devolver dos árboles que contienen todos los valores menores y todos los valores mayor que una valor dado split
se ejecuta en O (lg n) utilizando un solo pase a través del árbol, por lo que puede podar ramas enteras de su árbol de una sola vez, siempre que sepa en qué valor se divide.
Pero si quiero quitar el máximo n elementos ... puedo sólo hay que ejecutar el por encima de n veces, o hay una manera más rápida de hacer eso?
Usando mi clase Treap
:
open Treap
let nthLargest n t = Seq.nth n (Treap.toSeqBack t)
let removeTopN n t =
let largest = nthLargest n t
let smallerValues, wasFound, largerValues = t.Split(largest)
smallerValues
let e = Treap.empty(fun (x : int) (y : int) -> x.CompareTo(y))
let t = [1 .. 100] |> Seq.fold (fun (acc : Treap<_>) x -> acc.Insert(x)) e
let t' = removeTopN 10 t
removeTopN
carreras en tiempo O (n + lg m), donde n es el índice en la secuencia de árbol y m es el número de elementos en el árbol.
que no ofrecen ninguna garantía sobre la exactitud de mi código, utilice a su propio riesgo;)
Podría describir exactamente los requisitos que necesita de su estructura de datos? ¿Necesita una estructura de datos similar a un montón para un acceso rápido a artículos min/max, o necesita un acceso aleatorio rápido a su lista también? ¿Necesita algo más exótico como un árbol de rango para consultar los rangos de artículos? – Juliet
Este es un seguimiento de mi pregunta anterior http://stackoverflow.com/questions/3407772/f-immutable-variable-sized-window-data-structure Entonces ... en general, solo necesito agregar cosas el frente, y eliminar cosas de la parte posterior. Estoy haciendo esta pregunta porque si ejecuto s.Remove (s.MaximumElement) 10 veces, creará 10 estructuras de datos intermedias inmutables ... parece que una operación "inteligente" podría "eliminar" todos los 10 últimos nodos y devolver la nueva estructura. – mentics