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 list
ya 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 sort
usa?
¿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
B
ser ordenados inicial yalist
eA
yC
listas inicialmente vacías. DividirB
en dos partesB1
,B2
de longitudesm
ym
om+1
ym
, compararnewelt
con el primer elemento deB2
. Sinewelt
se≥
extiendeA
a la derecha conB1
y reemplazaB
conB2
, de lo contrario, se extiendeC
a la izquierda conB2
y reemplazaB
conB1
. Después deO(log n)
tales pasos no queda nada adentroB
. LuegoA
contiene las cosas≤ newelt
, yC
esas> newelt
, y la concatenación produce la lista ordenada extendida. Disculpas por ele-lisp
lenguaje no muy parecido.Respuestas:
Si tiene instalado el código fuente de Emacs, puede encontrar el código fuente
sort
conM-x find-function
.Allí puede ver que
sort
realiza 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
sort
tiene 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