-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHeapSort.swift
More file actions
78 lines (67 loc) · 2.32 KB
/
HeapSort.swift
File metadata and controls
78 lines (67 loc) · 2.32 KB
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
71
72
73
74
75
76
77
78
extension Array where Element : Comparable {
mutating func heapSort(by areInIncreasingOrder: @escaping (Element, Element) -> Bool) {
let heap = BinaryHeap(from: self, by: areInIncreasingOrder)
var index = 0
while heap.size() > 0 {
self[index] = heap.extractTop()!
index = index + 1
}
}
}
class BinaryHeap<T: Comparable> {
private var elements: [T] = []
private var areInIncreasingOrder: (T, T) -> Bool
init(ofType: T.Type, by areInIncreasingOrder: @escaping (T, T) -> Bool) {
self.elements = []
self.areInIncreasingOrder = areInIncreasingOrder
}
init(from array: [T], by areInIncreasingOrder: @escaping (T, T) -> Bool) {
self.areInIncreasingOrder = areInIncreasingOrder
for elem in array {
insert(elem)
}
}
func insert(_ element: T) {
elements.append(element)
var elementIndex = elements.count - 1
while true {
let parentIndex = (elementIndex - 1) / 2
if parentIndex >= 0 && areInIncreasingOrder(elements[elementIndex], elements[parentIndex]) {
elements.swapAt(elementIndex, parentIndex)
elementIndex = parentIndex
} else {
break
}
}
}
func removeTop() {
if elements.count <= 0 { return }
var parentIndex = 0
elements[parentIndex] = elements.last!
elements.removeLast()
while true {
let indexLeftSon = 2*parentIndex + 1
var indexRightSon = 2*parentIndex + 2
if indexLeftSon >= elements.count { break }
if indexRightSon >= elements.count { indexRightSon = indexLeftSon }
let swapingIndex = areInIncreasingOrder(elements[indexLeftSon] , elements[indexRightSon]) ? indexLeftSon : indexRightSon
if areInIncreasingOrder(elements[swapingIndex], elements[parentIndex]) {
elements.swapAt(swapingIndex, parentIndex)
parentIndex = swapingIndex
} else {
break
}
}
}
func size() -> Int {
return elements.count
}
func top() -> T? {
return elements.first
}
func extractTop() -> T? {
let res = elements.first
removeTop()
return res
}
}