Skip to content

Instantly share code, notes, and snippets.

@alco
Created March 20, 2012 13:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alco/2135276 to your computer and use it in GitHub Desktop.
Save alco/2135276 to your computer and use it in GitHub Desktop.
Mergesort in Clojure
(defn merge-seqs
"Merges two sorted sequences into a single sorted sequence"
([left right]
(merge-seqs (list left right)))
([[left right]]
(loop [l left, r right, result []]
(let [lhead (first l), rhead (first r)]
(cond
(nil? lhead) (concat result r)
(nil? rhead) (concat result l)
(<= lhead rhead) (recur (rest l) r (conj result lhead))
true (recur l (rest r) (conj result rhead)))))))
(defn mergesort
"Produces a sorted sequence from an input sequence.
Works best with vectors (since it uses 'count' internally)."
[xs]
((fn mergesort-counted [xs n]
(if (<= n 1)
xs
(let [middle (bit-shift-right n 1)] ; fast division by 2
(merge-seqs (map mergesort-counted
(split-at middle xs) ; two halves
[middle (- n middle)]))))) ; count of each half
xs (count xs)))
Copy link

ghost commented Sep 15, 2013

A little simpler approach: https://gist.github.com/baabelfish/6573984

@ktkonrad
Copy link

Here's a lazy version that works on multiple sequences: http://blog.malcolmsparks.com/?p=42. Pretty nice.

@egri-nagy
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment