6
6
public struct Heap < T> {
7
7
/** The array that stores the heap's nodes. */
8
8
var elements = [ T] ( )
9
-
9
+
10
10
/** Determines whether this is a max-heap (>) or min-heap (<). */
11
11
fileprivate var isOrderedBefore : ( T , T ) -> Bool
12
-
12
+
13
13
/**
14
14
* Creates an empty heap.
15
15
* The sort function determines whether this is a min-heap or max-heap.
@@ -18,7 +18,7 @@ public struct Heap<T> {
18
18
public init ( sort: @escaping ( T , T ) -> Bool ) {
19
19
self . isOrderedBefore = sort
20
20
}
21
-
21
+
22
22
/**
23
23
* Creates a heap from an array. The order of the array does not matter;
24
24
* the elements are inserted into the heap in the order determined by the
@@ -28,17 +28,17 @@ public struct Heap<T> {
28
28
self . isOrderedBefore = sort
29
29
buildHeap ( fromArray: array)
30
30
}
31
-
31
+
32
32
/*
33
- // This version has O(n log n) performance.
34
- private mutating func buildHeap(array: [T]) {
35
- elements.reserveCapacity(array.count)
36
- for value in array {
37
- insert(value)
38
- }
39
- }
40
- */
41
-
33
+ // This version has O(n log n) performance.
34
+ private mutating func buildHeap(array: [T]) {
35
+ elements.reserveCapacity(array.count)
36
+ for value in array {
37
+ insert(value)
38
+ }
39
+ }
40
+ */
41
+
42
42
/**
43
43
* Converts an array to a max-heap or min-heap in a bottom-up manner.
44
44
* Performance: This runs pretty much in O(n).
@@ -49,23 +49,23 @@ public struct Heap<T> {
49
49
shiftDown ( i, heapSize: elements. count)
50
50
}
51
51
}
52
-
52
+
53
53
public var isEmpty : Bool {
54
54
return elements. isEmpty
55
55
}
56
-
56
+
57
57
public var count : Int {
58
58
return elements. count
59
59
}
60
-
60
+
61
61
/**
62
62
* Returns the index of the parent of the element at index i.
63
63
* The element at index 0 is the root of the tree and has no parent.
64
64
*/
65
65
@inline ( __always) func parentIndex( ofIndex i: Int ) -> Int {
66
66
return ( i - 1 ) / 2
67
67
}
68
-
68
+
69
69
/**
70
70
* Returns the index of the left child of the element at index i.
71
71
* Note that this index can be greater than the heap size, in which case
@@ -74,7 +74,7 @@ public struct Heap<T> {
74
74
@inline ( __always) func leftChildIndex( ofIndex i: Int ) -> Int {
75
75
return 2 * i + 1
76
76
}
77
-
77
+
78
78
/**
79
79
* Returns the index of the right child of the element at index i.
80
80
* Note that this index can be greater than the heap size, in which case
@@ -83,15 +83,15 @@ public struct Heap<T> {
83
83
@inline ( __always) func rightChildIndex( ofIndex i: Int ) -> Int {
84
84
return 2 * i + 2
85
85
}
86
-
86
+
87
87
/**
88
88
* Returns the maximum value in the heap (for a max-heap) or the minimum
89
89
* value (for a min-heap).
90
90
*/
91
91
public func peek( ) -> T ? {
92
92
return elements. first
93
93
}
94
-
94
+
95
95
/**
96
96
* Adds a new value to the heap. This reorders the heap so that the max-heap
97
97
* or min-heap property still holds. Performance: O(log n).
@@ -100,25 +100,25 @@ public struct Heap<T> {
100
100
elements. append ( value)
101
101
shiftUp ( elements. count - 1 )
102
102
}
103
-
103
+
104
104
public mutating func insert< S: Sequence > ( _ sequence: S ) where S. Iterator. Element == T {
105
105
for value in sequence {
106
106
insert ( value)
107
107
}
108
108
}
109
-
109
+
110
110
/**
111
111
* Allows you to change an element. In a max-heap, the new element should be
112
112
* larger than the old one; in a min-heap it should be smaller.
113
113
*/
114
114
public mutating func replace( index i: Int , value: T ) {
115
115
guard i < elements. count else { return }
116
-
116
+
117
117
assert ( isOrderedBefore ( value, elements [ i] ) )
118
118
elements [ i] = value
119
119
shiftUp ( i)
120
120
}
121
-
121
+
122
122
/**
123
123
* Removes the root node from the heap. For a max-heap, this is the maximum
124
124
* value; for a min-heap it is the minimum value. Performance: O(log n).
@@ -137,23 +137,23 @@ public struct Heap<T> {
137
137
return value
138
138
}
139
139
}
140
-
140
+
141
141
/**
142
142
* Removes an arbitrary node from the heap. Performance: O(log n). You need
143
143
* to know the node's index, which may actually take O(n) steps to find.
144
144
*/
145
145
public mutating func removeAt( _ index: Int ) -> T ? {
146
146
guard index < elements. count else { return nil }
147
-
147
+
148
148
let size = elements. count - 1
149
149
if index != size {
150
- swap ( & elements[ index] , & elements [ size] )
150
+ elements. swapAt ( index, size)
151
151
shiftDown ( index, heapSize: size)
152
152
shiftUp ( index)
153
153
}
154
154
return elements. removeLast ( )
155
155
}
156
-
156
+
157
157
/**
158
158
* Takes a child node and looks at its parents; if a parent is not larger
159
159
* (max-heap) or not smaller (min-heap) than the child, we exchange them.
@@ -162,31 +162,31 @@ public struct Heap<T> {
162
162
var childIndex = index
163
163
let child = elements [ childIndex]
164
164
var parentIndex = self . parentIndex ( ofIndex: childIndex)
165
-
165
+
166
166
while childIndex > 0 && isOrderedBefore ( child, elements [ parentIndex] ) {
167
167
elements [ childIndex] = elements [ parentIndex]
168
168
childIndex = parentIndex
169
169
parentIndex = self . parentIndex ( ofIndex: childIndex)
170
170
}
171
-
171
+
172
172
elements [ childIndex] = child
173
173
}
174
-
174
+
175
175
mutating func shiftDown( ) {
176
176
shiftDown ( 0 , heapSize: elements. count)
177
177
}
178
-
178
+
179
179
/**
180
180
* Looks at a parent node and makes sure it is still larger (max-heap) or
181
181
* smaller (min-heap) than its childeren.
182
182
*/
183
183
mutating func shiftDown( _ index: Int , heapSize: Int ) {
184
184
var parentIndex = index
185
-
185
+
186
186
while true {
187
187
let leftChildIndex = self . leftChildIndex ( ofIndex: parentIndex)
188
188
let rightChildIndex = leftChildIndex + 1
189
-
189
+
190
190
// Figure out which comes first if we order them by the sort function:
191
191
// the parent, the left child, or the right child. If the parent comes
192
192
// first, we're done. If not, that element is out-of-place and we make
@@ -199,8 +199,8 @@ public struct Heap<T> {
199
199
first = rightChildIndex
200
200
}
201
201
if first == parentIndex { return }
202
-
203
- swap ( & elements[ parentIndex] , & elements [ first] )
202
+
203
+ elements. swapAt ( parentIndex, first)
204
204
parentIndex = first
205
205
}
206
206
}
@@ -215,7 +215,7 @@ extension Heap where T: Equatable {
215
215
public func index( of element: T ) -> Int ? {
216
216
return index ( of: element, 0 )
217
217
}
218
-
218
+
219
219
fileprivate func index( of element: T , _ i: Int ) -> Int ? {
220
220
if i >= count { return nil }
221
221
if isOrderedBefore ( element, elements [ i] ) { return nil }
0 commit comments