Necesito agregar un solo entero a una lista que ya está ordenada, de modo que vaya en el lugar correcto. Mi primer pensamiento fue algo como
(sort (cons newelt list) #'<)
Sin embargo, dado que listya está ordenado, solo se necesita una inserción, lo que significa que esta solución podría ser terriblemente inadecuada dependiendo del algoritmo utilizado sort.
Entonces, ¿ cuál es el algoritmo que sortusa?
¿Sería mejor hacer algo como lo siguiente?
(let ((tail list))
;; The first element is never less-than
(while (and tail (< newelt (cadr tail)))
(setq tail (cdr tail)))
(setcdr tail (cons newelt (cdr tail)))
list)
elisp
performance
emacs-internals
Malabarba
fuente
fuente

Bser ordenados inicial yalisteAyClistas inicialmente vacías. DividirBen dos partesB1,B2de longitudesmymom+1ym, compararneweltcon el primer elemento deB2. Sineweltse≥extiendeAa la derecha conB1y reemplazaBconB2, de lo contrario, se extiendeCa la izquierda conB2y reemplazaBconB1. Después deO(log n)tales pasos no queda nada adentroB. LuegoAcontiene las cosas≤ newelt, yCesas> newelt, y la concatenación produce la lista ordenada extendida. Disculpas por ele-lisplenguaje no muy parecido.Respuestas:
Si tiene instalado el código fuente de Emacs, puede encontrar el código fuente
sortconM-x find-function.Allí puede ver que
sortrealiza una ordenación por fusión. Comprueba la longitud de la lista, la divide por la mitad, clasifica las partes "frontal" y "posterior" por separado a través de la recursión, y luego combina las dos.En cuanto a si su implementación sería más rápida, ¡mídala! Es más eficiente en teoría (O (n) frente a O (n log n)), pero
sorttiene la ventaja de estar escrito en C, por lo que el resultado podría ser de cualquier manera. (Por supuesto, no olvide compilar en bytes su función).fuente