Muszę dodać jedną liczbę całkowitą do listy, która jest już posortowana, tak aby trafiła we właściwe miejsce. Moja pierwsza myśl była podobna
(sort (cons newelt list) #'<)
Jednak biorąc pod uwagę, że list
jest już posortowane, naprawdę potrzebne jest tylko jedno wstawienie, co oznacza, że to rozwiązanie może być strasznie nieodpowiednie w zależności od używanego algorytmu sort
.
Więc jakiego algorytmu sort
używa?
Czy lepiej byłoby zrobić coś takiego?
(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
źródło
źródło
B
być początkowa już posortowanelist
iA
iC
początkowo pustych list. PodzielB
na dwie częściB1
,B2
o długościm
im
lubm+1
im
, i porównajnewelt
z pierwszym elementemB2
. Jeślinewelt
znaczy≥
przedłużyćA
jego prawej zB1
i wymienićB
zB2
, jeszcze przedłużyćC
jego lewejB2
i wymienićB
zB1
. PoO(log n)
takich krokach nic nie zostajeB
. NastępnieA
zawiera rzeczy≤ newelt
iC
te> newelt
, a konkatenacja tworzy rozszerzoną posortowaną listę. Przepraszamy za niezbyte-lisp
podobny język.Odpowiedzi:
Jeśli masz kod źródłowy Emacs zainstalowany, można znaleźć kod źródłowy
sort
zM-x find-function
.Tam możesz zobaczyć, że
sort
wykonuje sortowanie scalające. Sprawdza długość listy, dzieli listę na pół, sortuje części „przednią” i „tylną” osobno poprzez rekurencję, a następnie łączy je.Jeśli chodzi o to, czy Twoja implementacja będzie szybsza - zmierz to! Teoretycznie jest bardziej wydajny (O (n) vs O (n log n)), ale
sort
ma tę zaletę, że jest napisany w C, więc wynik może pójść w obie strony. (Oczywiście nie zapomnij skompilować bajtów swojej funkcji.)źródło