mergeSort in swift

This commit is contained in:
Wenru Dong 2018-10-16 22:25:52 +01:00
parent d8f7f90bd3
commit 422b1a59bd
3 changed files with 98 additions and 0 deletions

BIN
swift/12_sorts/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,44 @@
//
// SortsTests.swift
// SortsTests
//
// Created by Wenru Dong on 2018/10/14.
// Copyright © 2018 Wenru Dong. All rights reserved.
//
import XCTest
class SortsTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testMergeSort() {
var a1 = [1, 1, 1, 1]
mergeSort(&a1)
XCTAssertEqual(a1, [1, 1, 1, 1])
var a2 = [4, 3, 2, 1]
mergeSort(&a2)
XCTAssertEqual(a2, [1, 2, 3, 4])
var a3 = [3, 6, 9, 7, 8, -1, 9, 3, -2, 0]
mergeSort(&a3)
XCTAssertEqual(a3, [-2, -1, 0, 3, 3, 6, 7, 8, 9, 9])
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}

View File

@ -0,0 +1,54 @@
//
// sorts.swift
// algo
//
// Created by Wenru Dong on 2018/10/14.
// Copyright © 2018 Wenru Dong. All rights reserved.
//
import Foundation
public func mergeSort<T>(_ a: inout T) where T: RandomAccessCollection, T: MutableCollection, T.Element: Comparable {
mergeSort(&a, from: a.startIndex, to: a.index(before: a.endIndex))
}
fileprivate func mergeSort<T>(_ a: inout T, from low: T.Index, to high: T.Index) where T: RandomAccessCollection, T: MutableCollection, T.Element: Comparable {
if low >= high { return }
let dist = a.distance(from: low, to: high)
let mid = a.index(low, offsetBy: dist/2)
mergeSort(&a, from: low, to: mid)
mergeSort(&a, from: a.index(mid, offsetBy: 1), to: high)
print(a)
merge(&a, from: low, through: mid, to: high)
}
fileprivate func merge<T>(_ a: inout T, from low: T.Index, through mid: T.Index, to high: T.Index) where T: RandomAccessCollection, T: MutableCollection, T.Element: Comparable {
var i = low
var j = a.index(mid, offsetBy: 1)
var tmp = Array<T.Element>()
tmp.reserveCapacity(a.distance(from: low, to: high) + 1)
while i <= mid && j <= high {
if a[i] <= a[j] {
tmp.append(a[i])
a.formIndex(after: &i)
} else {
tmp.append(a[j])
a.formIndex(after: &j)
}
}
var start = i
var end = mid
if j <= high {
start = j
end = high
}
tmp.append(contentsOf: a[start...end])
var current = low
for element in tmp {
a[current] = element
print(element)
a.formIndex(after: &current)
}
}