Skip to content

Commit

Permalink
Add insertion-sort.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorge Tavares committed Feb 1, 2012
1 parent cd97add commit 0484472
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
51 changes: 51 additions & 0 deletions insertion-sort.lisp
@@ -0,0 +1,51 @@
;;;; Copyright (c) 2012 Jorge Tavares <jorge.tavares@ieee.org>
;;;;
;;;; Permission is hereby granted, free of charge, to any person obtaining
;;;; a copy of this software and associated documentation files (the
;;;; "Software"), to deal in the Software without restriction, including
;;;; without limitation the rights to use, copy, modify, merge, publish,
;;;; distribute, sublicense, and/or sell copies of the Software, and to
;;;; permit persons to whom the Software is furnished to do so, subject to
;;;; the following conditions:
;;;;
;;;; The above copyright notice and this permission notice shall be included
;;;; in all copies or substantial portions of the Software.
;;;;
;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
;;;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
;;;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
;;;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
;;;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

(in-package :usort)

;;;
;;; insertion sort
;;;

(defun insertion-sort (sequence predicate &key key)
(%insertion-sort sequence 0 (length sequence) predicate (or key #'identity))
sequence)

(defun %insertion-sort (sequence start end predicate key)
(declare (type function predicate key)
(type fixnum start end)
(type simple-vector sequence)
(optimize (speed 3) (safety 0)))
;; the start arg is actually not necessary but it is included
;; to facilitate the use of insertion sort in other sorting
;; algorithms like quicksort with insertion for small values
(loop for j from (1+ start) below end
do (let* ((pivot (aref sequence j))
(data (funcall key pivot))
(i (1- j)))
(declare (type fixnum i))
(loop while (and (>= i start)
(funcall predicate data (funcall key (aref sequence i))))
do (setf (aref sequence (1+ i)) (aref sequence i)
i (1- i)))
(setf (aref sequence (1+ i)) pivot))))


1 change: 1 addition & 0 deletions packages.lisp
Expand Up @@ -23,5 +23,6 @@
(:use :cl)
(:documentation "Portable and optimized sorting algorithms.")
(:export
#:insertion-sort
#:quicksort
))
10 changes: 8 additions & 2 deletions quicksort.lisp
Expand Up @@ -34,9 +34,15 @@
(type function predicate key)
(type simple-vector sequence)
(optimize (speed 3) (safety 0)))
;; the while loop avoids the second recursive call
;; to quicksort made at the end of the loop body
(loop while (< start end)
do (let* ((i start)
(j (1+ end))
;; the pivot is chosen with an adapted median-of-3 method
;; instead of picking 3 random numbers and use the middle
;; value, the pivot is picked by the median of start and
;; end. this way we avoid the use of the random generator
(p (+ start (ash (- end start) -1)))
(x (aref sequence p)))
(declare (fixnum i j p))
Expand All @@ -56,6 +62,8 @@
(rotatef (aref sequence i) (aref sequence j))))
(setf (aref sequence start) (aref sequence j)
(aref sequence j) x)
;; check each partition is smaller and pick the smallest one
;; this way the stack depth worst-case is Theta(lgn)
(if (< (- j start) (- end j))
(progn
(%quicksort sequence start (1- j) predicate key)
Expand All @@ -64,5 +72,3 @@
(%quicksort sequence (1+ j) end predicate key)
(setf end (1- j)))))))



3 changes: 2 additions & 1 deletion usort.asd
Expand Up @@ -25,7 +25,8 @@
:author "Jorge Tavares <jorge.tavares@ieee.org>"
:licence "MIT"
:serial t
:components ((:file "packages")
:components ((:file "packages")
(:file "insertion-sort")
(:file "quicksort")
(:static-file "README")
(:static-file "LICENSE")))

0 comments on commit 0484472

Please sign in to comment.