;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function Mergesort - relies on function merge, and recursion: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun mergesort(x) " ;; Examples: (mergesort-tester 10) (mergesort-tester 20) (mergesort-tester 30) " (let ((n (length x))) ;; if the list is of length 1, simply return it (no comparisons necessary) (if (= 1 n) x ;; otherwise, (let* ( ;; split the list - (half (floor (/ n 2))) (lhalf (select x (iseq half))) (rhalf (select x (iseq half (- n 1)))) ) ;; and merge the two halves once they've been sorted: (merge (mergesort lhalf) (mergesort rhalf) ) ) ) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function merge - merges two lists (recursive) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun merge(x y) ;; if either list is of length 0, then we can simply return the other half (if (or (= 0 (length x)) (= 0 (length y)) ) ;; if x is empty, return y; else return x: (if (= 0 (length x)) y x) ;; otherwise, (let () ;; increment the (global) variable compares, (incf compares) ;; and compare the first elements: (if (< (first x) (first y)) ;; we plop (first x) into the top spot, merge the rest, and combine ;; the results into a single list: (combine (list (first x) (merge (rest x) y))) ;; otherwise, we plop (first y) into the top spot, merge the rest, and ;; combine the results into a single list: (combine (list (first y) (merge x (rest y)))) ) ) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function comparisons - simply calculates the theoretical "worst-case ;; scenario" ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun comparisons(n) (- (* n (/ (ln n) (ln 2))) (- n 1))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function mergesort-tester - tests mergesort ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun mergesort-tester(n) (def compares 0) (def a (sample (iseq (* 2 n)) n)) (print a) (print (mergesort a)) (print compares) (print (comparisons n)) nil ) #| Some results of testing mergesort: ;; Examples: (mergesort-tester 10) (mergesort-tester 20) (mergesort-tester 30) (5 1 2 12 11 9 7 14 0 8) (0 1 2 5 7 8 9 11 12 14) 23 24.219280948873624 nil (20 4 33 3 27 28 9 32 0 6 22 39 17 23 13 26 36 14 25 11) (0 3 4 6 9 11 13 14 17 20 22 23 25 26 27 28 32 33 36 39) 66 67.43856189774725 nil (46 12 22 19 38 8 25 42 15 29 59 28 57 49 5 58 44 20 3 18 31 51 14 21 1 41 33 36 24 23) (1 3 5 8 12 14 15 18 19 20 21 22 23 24 25 28 29 31 33 36 38 41 42 44 46 49 51 57 58 59) 113 118.20671786825557 nil |#