Skip to content

Instantly share code, notes, and snippets.

@ryanbaldwin
Last active October 2, 2015 22:34
Show Gist options
  • Save ryanbaldwin/dba778f7e5af48d90016 to your computer and use it in GitHub Desktop.
Save ryanbaldwin/dba778f7e5af48d90016 to your computer and use it in GitHub Desktop.
A mergesort implemented in Clojure; Takes any number of unordered lists and merges them into a single merged list.
(ns ward.mergesort
(:refer-clojure :exclude [merge]))
(defn merge
"Merges two sorted lists into a single sorted list."
[right left]
(flatten (loop [r right, l left, results []]
(let [rhead (first r)
lhead (first l)]
(cond (nil? rhead) (conj results l)
(nil? lhead) (conj results r)
(< (compare lhead rhead) 1) (recur (rest l) r (conj results lhead))
:else (recur l (rest r) (conj results rhead)))))))
(defn mergesort
"Performs a mergesort on any number of unordered lists, producing a single ordered list."
([items]
(if (<= (count items) 1)
items
(let [midpoint (/ (count items) 2)
left (mergesort (take midpoint items))
right (mergesort (drop midpoint items))]
(merge left right))))
([items & more]
(let [merged-items (map mergesort (conj more items))]
(reduce merge merged-items))))
@ryanbaldwin
Copy link
Author

Changed line 12 to use compare instead of the straight up < against the raw values. This allows the merge to now use anything that implements Comparable, including strings and, uh, other stuff.

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