Ich muss einer Liste, die bereits sortiert ist, eine einzelne Ganzzahl hinzufügen, damit sie an der richtigen Stelle abgelegt wird. Mein erster Unterricht war so etwas wie
(sort (cons newelt list) #'<)
Da dies list
jedoch bereits sortiert ist, wird nur eine Einfügung wirklich benötigt, was bedeutet, dass diese Lösung je nach dem von verwendeten Algorithmus fürchterlich ungeeignet sein kann sort
.
Welcher Algorithmus wird sort
verwendet?
Wäre ich besser dran, wenn ich Folgendes täte?
(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
quelle
quelle
B
initial sein bereits sortiertlist
undA
undC
zunächst leere Listen. SplitB
in zwei TeileB1
,B2
von Längenm
undm
oderm+1
undm
, zu vergleichen ,newelt
um erste ElementB2
. Wennnewelt
heißt≥
verlängernA
mit seiner rechtenB1
und ersetzenB
mitB2
, sonst zu verlängern ,C
um seine linke mitB2
und ersetzenB
mitB1
. NachO(log n)
solchen Schritten ist nichts mehr drinB
. DannA
enthält die Dinge≤ newelt
, undC
diejenigen> newelt
, und Verkettung erzeugt die erweiterte sortierte Liste. Entschuldigung für nicht sehre-lisp
ähnliche Sprache.Antworten:
Wenn Sie den Emacs-Quellcode installiert haben, können Sie den Quellcode für
sort
mit findenM-x find-function
.Dort können Sie sehen, dass
sort
eine Zusammenführungssortierung durchgeführt wird. Es überprüft die Länge der Liste, zerlegt die Liste in zwei Hälften, sortiert die "vorderen" und "hinteren" Teile durch Rekursion getrennt und führt dann die beiden zusammen.Ob Ihre Implementierung schneller wäre - messen Sie es! Es ist theoretisch effizienter (O (n) vs O (n log n)),
sort
hat jedoch den Vorteil, dass es in C geschrieben wird, sodass das Ergebnis in beide Richtungen gehen kann. (Vergessen Sie natürlich nicht, Ihre Funktion byteweise zu kompilieren.)quelle