1
+ import scala .annotation .tailrec
2
+
3
+ sealed abstract class Heap [+ A ] { def rank : Int }
4
+
5
+ case object EmptyHeap extends Heap [Nothing ] { def rank = 0 }
6
+ case class NonEmptyHeap [A ](rank : Int , element : A , left : Heap [A ], right : Heap [A ]) extends Heap [A ]
7
+
8
+ /**
9
+ *
10
+ * Time complexity O(n log n)
11
+ */
12
+ object HeapSort {
13
+ def apply [A ](x : A ): Heap [A ] =
14
+ this (x, EmptyHeap , EmptyHeap )
15
+
16
+ def apply [A ](x : A , a : Heap [A ], b : Heap [A ]): Heap [A ] =
17
+ if (a.rank > b.rank) NonEmptyHeap (b.rank + 1 , x, a, b)
18
+ else NonEmptyHeap (a.rank + 1 , x, b, a)
19
+
20
+ def merge (a : Heap [Int ], b : Heap [Int ]): Heap [Int ] =
21
+ (a, b) match {
22
+ case (x, EmptyHeap ) => x
23
+ case (EmptyHeap , x) => x
24
+ case (x : NonEmptyHeap [Int ], y : NonEmptyHeap [Int ]) =>
25
+ if (x.element >= y.element) HeapSort (x.element, x.left, merge(x.right, y))
26
+ else HeapSort (y.element, y.left, merge(x, y.right))
27
+ }
28
+
29
+ def toList (heap : Heap [Int ]) =
30
+ toListWithMemory(List (), heap)
31
+
32
+ @ tailrec
33
+ def toListWithMemory (memo : List [Int ], heap : Heap [Int ]): List [Int ] =
34
+ heap match {
35
+ case EmptyHeap => memo
36
+ case x : NonEmptyHeap [Int ] =>
37
+ toListWithMemory(x.element :: memo, merge(x.left, x.right))
38
+ }
39
+
40
+ def sort (xs : Seq [Int ]): Seq [Int ] =
41
+ toList(xs.foldLeft(EmptyHeap : Heap [Int ])((memo, x) => merge(HeapSort (x), memo)))
42
+ }
43
+
44
+ object HeapSortImperative {
45
+ def heapify (a : Array [Int ], n : Int , i : Int ): Unit = {
46
+ var largest = i
47
+ var l = 2 * i + 1
48
+ var r = 2 * i + 2
49
+
50
+ if (l < n && a(i) < a(l)) {
51
+ largest = l
52
+ }
53
+
54
+ if (r < n && a(largest) < a(r)) {
55
+ largest = r
56
+ }
57
+
58
+ if (largest != i) {
59
+ val tmp = a(i)
60
+ a(i) = a(largest)
61
+ a(largest) = tmp
62
+
63
+ heapify(a, n, largest)
64
+ }
65
+ }
66
+
67
+ def sort (a : Array [Int ]) = {
68
+ val n = a.length
69
+
70
+ for (i <- n / 2 - 1 to 0 by - 1 ) {
71
+ println(i)
72
+ heapify(a, n, i)
73
+ }
74
+
75
+ for (i <- n - 1 to 0 by - 1 ) {
76
+ val tmp = a(i)
77
+ a(i) = a(0 )
78
+ a(0 ) = tmp
79
+
80
+ heapify(a, i, 0 )
81
+ }
82
+ }
83
+ }
0 commit comments