1
0
mirror of https://github.com/janet-lang/janet synced 2024-09-27 14:48:13 +00:00

Merge pull request #540 from felixr/better-quicksort

Improve quicksort to avoid worst case performance on sorted input
This commit is contained in:
Calvin Rose 2020-12-26 15:23:01 -06:00 committed by GitHub
commit 7242ee0186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -790,35 +790,38 @@
###
###
(defn- sort-part
[a lo hi by]
(def pivot (in a hi))
(var i lo)
(forv j lo hi
(def aj (in a j))
(when (by aj pivot)
(def ai (in a i))
(set (a i) aj)
(set (a j) ai)
(++ i)))
(set (a hi) (in a i))
(set (a i) pivot)
i)
(defn- median-of-three [a b c]
(if (not= (> a b) (> a c))
a
(if (not= (> b a) (> b c)) b c)))
(defn- sort-help
[a lo hi by]
(when (> hi lo)
(def piv (sort-part a lo hi by))
(sort-help a lo (- piv 1) by)
(sort-help a (+ piv 1) hi by))
(defn sort-help [a lo hi by]
(when (< lo hi)
(def pivot
(median-of-three (in a hi) (in a lo)
(in a (math/floor (/ (+ lo hi) 2)))))
(var left lo)
(var right hi)
(while true
(while (by (in a left) pivot) (++ left))
(while (by pivot (in a right)) (-- right))
(when (<= left right)
(def tmp (in a left))
(set (a left) (in a right))
(set (a right) tmp)
(++ left)
(-- right))
(if (>= left right) (break)))
(sort-help a lo right by)
(sort-help a left hi by))
a)
(defn sort
"Sort an array in-place. Uses quick-sort and is not a stable sort."
[a &opt by]
(sort-help a 0 (- (length a) 1) (or by <)))
(undef sort-part)
(undef median-of-three)
(undef sort-help)
(defn sort-by