Skip to content

Commit 0e0ae64

Browse files
committed
Merge remote-tracking branch 'raywenderlich/master'
2 parents 73cdecc + 7077bc1 commit 0e0ae64

File tree

8 files changed

+124
-94
lines changed

8 files changed

+124
-94
lines changed

Heap Sort/HeapSort.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
extension Heap {
22
public mutating func sort() -> [T] {
33
for i in stride(from: (elements.count - 1), through: 1, by: -1) {
4-
swap(&elements[0], &elements[i])
4+
elements.swapAt(0, i)
55
shiftDown(0, heapSize: i)
66
}
77
return elements
88
}
99
}
1010

1111
/*
12-
Sorts an array using a heap.
13-
Heapsort can be performed in-place, but it is not a stable sort.
14-
*/
12+
Sorts an array using a heap.
13+
Heapsort can be performed in-place, but it is not a stable sort.
14+
*/
1515
public func heapsort<T>(_ a: [T], _ sort: @escaping (T, T) -> Bool) -> [T] {
1616
let reverseOrder = { i1, i2 in sort(i2, i1) }
1717
var h = Heap(array: a, sort: reverseOrder)

Heap Sort/Tests/HeapSortTests.swift

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
import XCTest
22

33
class HeapSortTests: XCTestCase {
4+
func testSwift4() {
5+
// last checked with Xcode 9.0b4
6+
#if swift(>=4.0)
7+
print("Hello, Swift 4!")
8+
#endif
9+
}
10+
411
func testSort() {
512
var h1 = Heap(array: [5, 13, 2, 25, 7, 17, 20, 8, 4], sort: >)
613
let a1 = h1.sort()
714
XCTAssertEqual(a1, [2, 4, 5, 7, 8, 13, 17, 20, 25])
8-
15+
916
let a1_ = heapsort([5, 13, 2, 25, 7, 17, 20, 8, 4], <)
1017
XCTAssertEqual(a1_, [2, 4, 5, 7, 8, 13, 17, 20, 25])
11-
18+
1219
var h2 = Heap(array: [16, 14, 10, 8, 7, 8, 3, 2, 4, 1], sort: >)
1320
let a2 = h2.sort()
1421
XCTAssertEqual(a2, [1, 2, 3, 4, 7, 8, 8, 10, 14, 16])
15-
22+
1623
let a2_ = heapsort([16, 14, 10, 8, 7, 8, 3, 2, 4, 1], <)
1724
XCTAssertEqual(a2_, [1, 2, 3, 4, 7, 8, 8, 10, 14, 16])
18-
25+
1926
var h3 = Heap(array: [1, 2, 3, 4, 5, 6], sort: <)
2027
let a3 = h3.sort()
2128
XCTAssertEqual(a3, [6, 5, 4, 3, 2, 1])
22-
29+
2330
let a3_ = heapsort([1, 2, 3, 4, 5, 6], >)
2431
XCTAssertEqual(a3_, [6, 5, 4, 3, 2, 1])
2532
}

Heap Sort/Tests/Tests.xcodeproj/project.pbxproj

+15-3
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
isa = PBXProject;
8787
attributes = {
8888
LastSwiftUpdateCheck = 0720;
89-
LastUpgradeCheck = 0820;
89+
LastUpgradeCheck = 0900;
9090
ORGANIZATIONNAME = "Swift Algorithm Club";
9191
TargetAttributes = {
9292
7B2BBC7F1C779D720067B71D = {
@@ -145,14 +145,20 @@
145145
CLANG_CXX_LIBRARY = "libc++";
146146
CLANG_ENABLE_MODULES = YES;
147147
CLANG_ENABLE_OBJC_ARC = YES;
148+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
148149
CLANG_WARN_BOOL_CONVERSION = YES;
150+
CLANG_WARN_COMMA = YES;
149151
CLANG_WARN_CONSTANT_CONVERSION = YES;
150152
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
151153
CLANG_WARN_EMPTY_BODY = YES;
152154
CLANG_WARN_ENUM_CONVERSION = YES;
153155
CLANG_WARN_INFINITE_RECURSION = YES;
154156
CLANG_WARN_INT_CONVERSION = YES;
157+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
158+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
155159
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
160+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
161+
CLANG_WARN_STRICT_PROTOTYPES = YES;
156162
CLANG_WARN_SUSPICIOUS_MOVE = YES;
157163
CLANG_WARN_UNREACHABLE_CODE = YES;
158164
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -191,14 +197,20 @@
191197
CLANG_CXX_LIBRARY = "libc++";
192198
CLANG_ENABLE_MODULES = YES;
193199
CLANG_ENABLE_OBJC_ARC = YES;
200+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
194201
CLANG_WARN_BOOL_CONVERSION = YES;
202+
CLANG_WARN_COMMA = YES;
195203
CLANG_WARN_CONSTANT_CONVERSION = YES;
196204
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
197205
CLANG_WARN_EMPTY_BODY = YES;
198206
CLANG_WARN_ENUM_CONVERSION = YES;
199207
CLANG_WARN_INFINITE_RECURSION = YES;
200208
CLANG_WARN_INT_CONVERSION = YES;
209+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
210+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
201211
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
212+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
213+
CLANG_WARN_STRICT_PROTOTYPES = YES;
202214
CLANG_WARN_SUSPICIOUS_MOVE = YES;
203215
CLANG_WARN_UNREACHABLE_CODE = YES;
204216
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -230,7 +242,7 @@
230242
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
231243
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
232244
PRODUCT_NAME = "$(TARGET_NAME)";
233-
SWIFT_VERSION = 3.0;
245+
SWIFT_VERSION = 4.0;
234246
};
235247
name = Debug;
236248
};
@@ -242,7 +254,7 @@
242254
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
243255
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
244256
PRODUCT_NAME = "$(TARGET_NAME)";
245-
SWIFT_VERSION = 3.0;
257+
SWIFT_VERSION = 4.0;
246258
};
247259
name = Release;
248260
};

Heap Sort/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0820"
3+
LastUpgradeVersion = "0900"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
language = ""
2930
shouldUseLaunchSchemeArgsEnv = "YES">
3031
<Testables>
3132
<TestableReference
@@ -46,6 +47,7 @@
4647
buildConfiguration = "Debug"
4748
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
4849
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
50+
language = ""
4951
launchStyle = "0"
5052
useCustomWorkingDirectory = "NO"
5153
ignoresPersistentStateOnLaunch = "NO"

Heap/Heap.swift

+37-37
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
public struct Heap<T> {
77
/** The array that stores the heap's nodes. */
88
var elements = [T]()
9-
9+
1010
/** Determines whether this is a max-heap (>) or min-heap (<). */
1111
fileprivate var isOrderedBefore: (T, T) -> Bool
12-
12+
1313
/**
1414
* Creates an empty heap.
1515
* The sort function determines whether this is a min-heap or max-heap.
@@ -18,7 +18,7 @@ public struct Heap<T> {
1818
public init(sort: @escaping (T, T) -> Bool) {
1919
self.isOrderedBefore = sort
2020
}
21-
21+
2222
/**
2323
* Creates a heap from an array. The order of the array does not matter;
2424
* the elements are inserted into the heap in the order determined by the
@@ -28,17 +28,17 @@ public struct Heap<T> {
2828
self.isOrderedBefore = sort
2929
buildHeap(fromArray: array)
3030
}
31-
31+
3232
/*
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+
4242
/**
4343
* Converts an array to a max-heap or min-heap in a bottom-up manner.
4444
* Performance: This runs pretty much in O(n).
@@ -49,23 +49,23 @@ public struct Heap<T> {
4949
shiftDown(i, heapSize: elements.count)
5050
}
5151
}
52-
52+
5353
public var isEmpty: Bool {
5454
return elements.isEmpty
5555
}
56-
56+
5757
public var count: Int {
5858
return elements.count
5959
}
60-
60+
6161
/**
6262
* Returns the index of the parent of the element at index i.
6363
* The element at index 0 is the root of the tree and has no parent.
6464
*/
6565
@inline(__always) func parentIndex(ofIndex i: Int) -> Int {
6666
return (i - 1) / 2
6767
}
68-
68+
6969
/**
7070
* Returns the index of the left child of the element at index i.
7171
* Note that this index can be greater than the heap size, in which case
@@ -74,7 +74,7 @@ public struct Heap<T> {
7474
@inline(__always) func leftChildIndex(ofIndex i: Int) -> Int {
7575
return 2*i + 1
7676
}
77-
77+
7878
/**
7979
* Returns the index of the right child of the element at index i.
8080
* Note that this index can be greater than the heap size, in which case
@@ -83,15 +83,15 @@ public struct Heap<T> {
8383
@inline(__always) func rightChildIndex(ofIndex i: Int) -> Int {
8484
return 2*i + 2
8585
}
86-
86+
8787
/**
8888
* Returns the maximum value in the heap (for a max-heap) or the minimum
8989
* value (for a min-heap).
9090
*/
9191
public func peek() -> T? {
9292
return elements.first
9393
}
94-
94+
9595
/**
9696
* Adds a new value to the heap. This reorders the heap so that the max-heap
9797
* or min-heap property still holds. Performance: O(log n).
@@ -100,25 +100,25 @@ public struct Heap<T> {
100100
elements.append(value)
101101
shiftUp(elements.count - 1)
102102
}
103-
103+
104104
public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
105105
for value in sequence {
106106
insert(value)
107107
}
108108
}
109-
109+
110110
/**
111111
* Allows you to change an element. In a max-heap, the new element should be
112112
* larger than the old one; in a min-heap it should be smaller.
113113
*/
114114
public mutating func replace(index i: Int, value: T) {
115115
guard i < elements.count else { return }
116-
116+
117117
assert(isOrderedBefore(value, elements[i]))
118118
elements[i] = value
119119
shiftUp(i)
120120
}
121-
121+
122122
/**
123123
* Removes the root node from the heap. For a max-heap, this is the maximum
124124
* value; for a min-heap it is the minimum value. Performance: O(log n).
@@ -137,23 +137,23 @@ public struct Heap<T> {
137137
return value
138138
}
139139
}
140-
140+
141141
/**
142142
* Removes an arbitrary node from the heap. Performance: O(log n). You need
143143
* to know the node's index, which may actually take O(n) steps to find.
144144
*/
145145
public mutating func removeAt(_ index: Int) -> T? {
146146
guard index < elements.count else { return nil }
147-
147+
148148
let size = elements.count - 1
149149
if index != size {
150-
swap(&elements[index], &elements[size])
150+
elements.swapAt(index, size)
151151
shiftDown(index, heapSize: size)
152152
shiftUp(index)
153153
}
154154
return elements.removeLast()
155155
}
156-
156+
157157
/**
158158
* Takes a child node and looks at its parents; if a parent is not larger
159159
* (max-heap) or not smaller (min-heap) than the child, we exchange them.
@@ -162,31 +162,31 @@ public struct Heap<T> {
162162
var childIndex = index
163163
let child = elements[childIndex]
164164
var parentIndex = self.parentIndex(ofIndex: childIndex)
165-
165+
166166
while childIndex > 0 && isOrderedBefore(child, elements[parentIndex]) {
167167
elements[childIndex] = elements[parentIndex]
168168
childIndex = parentIndex
169169
parentIndex = self.parentIndex(ofIndex: childIndex)
170170
}
171-
171+
172172
elements[childIndex] = child
173173
}
174-
174+
175175
mutating func shiftDown() {
176176
shiftDown(0, heapSize: elements.count)
177177
}
178-
178+
179179
/**
180180
* Looks at a parent node and makes sure it is still larger (max-heap) or
181181
* smaller (min-heap) than its childeren.
182182
*/
183183
mutating func shiftDown(_ index: Int, heapSize: Int) {
184184
var parentIndex = index
185-
185+
186186
while true {
187187
let leftChildIndex = self.leftChildIndex(ofIndex: parentIndex)
188188
let rightChildIndex = leftChildIndex + 1
189-
189+
190190
// Figure out which comes first if we order them by the sort function:
191191
// the parent, the left child, or the right child. If the parent comes
192192
// first, we're done. If not, that element is out-of-place and we make
@@ -199,8 +199,8 @@ public struct Heap<T> {
199199
first = rightChildIndex
200200
}
201201
if first == parentIndex { return }
202-
203-
swap(&elements[parentIndex], &elements[first])
202+
203+
elements.swapAt(parentIndex, first)
204204
parentIndex = first
205205
}
206206
}
@@ -215,7 +215,7 @@ extension Heap where T: Equatable {
215215
public func index(of element: T) -> Int? {
216216
return index(of: element, 0)
217217
}
218-
218+
219219
fileprivate func index(of element: T, _ i: Int) -> Int? {
220220
if i >= count { return nil }
221221
if isOrderedBefore(element, elements[i]) { return nil }

0 commit comments

Comments
 (0)