Preciso adicionar um único número inteiro a uma lista que já esteja classificada, de modo que fique no lugar certo. Meu primeiro pensamento foi algo como
(sort (cons newelt list) #'<)
No entanto, dado que list
já está classificado, apenas uma inserção é realmente necessária, o que significa que esta solução pode ser terrivelmente inadequada, dependendo do algoritmo usado por sort
.
Então, qual é o algoritmo que sort
usa?
Seria melhor fazer algo como o seguinte?
(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
fonte
fonte
B
ser inicial já ordenadoslist
eA
eC
listas inicialmente vazias. DividaB
em duas partesB1
,B2
de comprimentosm
em
oum+1
em
, comparenewelt
com o primeiro elemento deB2
. Senewelt
é≥
estenderA
a sua direita comB1
e substituirB
comB2
, senão estenderC
à sua esquerda comB2
e substituirB
comB1
. ApósO(log n)
essas etapas, não resta nadaB
. Em seguida,A
contém as coisas≤ newelt
eC
essas> newelt
e a concatenação produz a lista classificada estendida. Desculpas por nãoe-lisp
gostar muito da linguagem.Respostas:
Se você tiver o código fonte do Emacs instalado, poderá encontrar o código fonte
sort
comM-x find-function
.Lá você pode ver que
sort
realiza uma classificação de mesclagem. Ele verifica o comprimento da lista, divide a lista pela metade, classifica as partes "frontal" e "traseira" separadamente por meio de recursão e depois mescla as duas.Quanto à sua implementação ser mais rápida, meça-a! É mais eficiente em teoria (O (n) vs O (n log n)), mas
sort
tem a vantagem de ser escrito em C, portanto o resultado pode ser de qualquer maneira. (Obviamente, não se esqueça de compilar sua função com bytes).fonte