mergesort[procedure] mergesort less? lst
(def mergesort (less? lst)
(with (n (len lst))
(if (<= n 1) lst
; ; check if the list is already sorted
; ; (which can be a common case, eg, directory lists).
; (let loop ([last (car lst)] [next (cdr lst)])
; (or (null? next)
; (and (not (less? (car next) last))
; (loop (car next) (cdr next)))))
; lst
((afn (n)
(if (> n 2)
; needs to evaluate L->R
(withs (j (/ (if (even n) n (- n 1)) 2) ; faster than round
a (self j)
b (self (- n j)))
(merge less? a b))
; the following case just inlines the length 2 case,
; it can be removed (and use the above case for n>1)
; and the code still works, except a little slower
(is n 2)
(with (x (car lst) y (cadr lst) p lst)
(= lst (cddr lst))
(when (less? y x) (scar p y) (scar (cdr p) x))
(scdr (cdr p) nil)
p)
(is n 1)
(with (p lst)
(= lst (cdr lst))
(scdr p nil)
p)
nil))
n))))
|