-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap_sort.clj
70 lines (60 loc) · 1.66 KB
/
heap_sort.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(ns code-problems.heap-sort)
(defn last-i
[vector]
(dec(count vector)))
(defn left-child-i
[i]
(inc (* 2 i)))
(defn right-child-i
[i]
(+ (* 2 i) 2))
(defn parent-i
[i]
(quot (dec i) 2))
(defn heapify-start-i
[vector]
(parent-i (last-i vector)))
(defn swap
[vector a b]
(let [va (get vector a)
vb (get vector b)]
(assoc (assoc vector a vb) b va)))
(defn sift-down
[vector i]
(if (> (left-child-i i) (last-i vector))
vector
(let [left-child (get vector (left-child-i i))
value (get vector i)
right-child (get vector (right-child-i i))]
(if (= i 0)
(cond
(< value left-child) (swap vector i (left-child-i i))
(and (some? right-child) (< value right-child)) (swap vector i (right-child-i i))
:else vector)
(cond
(< value left-child) (sift-down (swap vector i (left-child-i i)) (parent-i i))
(and (some? right-child) (< value right-child)) (sift-down (swap vector i (right-child-i i)) (parent-i i))
:else vector)))))
(defn heapify
[vector]
(if (<= (count vector) 1)
vector
(loop [v vector
i (heapify-start-i vector)]
(if (< i 0)
v
(recur (sift-down v i) (dec i))))))
(defn heap-remove-first-and-heapify
[vector]
(if (<= (count vector) 1)
[(first vector) []]
[(first vector) (sift-down (subvec (swap vector 0 (last-i vector)) 0 (last-i vector)) 0)]))
(defn heap-sort
[vector]
(loop [result []
v (heapify vector)
i (count vector)]
(if (= i 0)
result
(let [[val vec] (heap-remove-first-and-heapify v)]
(recur (conj result val) vec (dec i))))))