forked from ambujraj/hacktoberfest2018
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMerge-Sort.swift
94 lines (80 loc) · 2.19 KB
/
Merge-Sort.swift
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
// Mergesort.swift
//
//
// Created by Alex Wellnitz on 06-10-2018.
//
//
func mergeSort<T: Comparable>(_ array: [T]) -> [T] {
guard array.count > 1 else { return array }
let middleIndex = array.count / 2
let leftArray = mergeSort(Array(array[0..<middleIndex]))
let rightArray = mergeSort(Array(array[middleIndex..<array.count]))
return merge(leftPile: leftArray, rightPile: rightArray)
}
func merge<T: Comparable>(leftPile: [T], rightPile: [T]) -> [T] {
var leftIndex = 0
var rightIndex = 0
var orderedPile: [T] = []
if orderedPile.capacity < leftPile.count + rightPile.count {
orderedPile.reserveCapacity(leftPile.count + rightPile.count)
}
while true {
guard leftIndex < leftPile.endIndex else {
orderedPile.append(contentsOf: rightPile[rightIndex..<rightPile.endIndex])
break
}
guard rightIndex < rightPile.endIndex else {
orderedPile.append(contentsOf: leftPile[leftIndex..<leftPile.endIndex])
break
}
if leftPile[leftIndex] < rightPile[rightIndex] {
orderedPile.append(leftPile[leftIndex])
leftIndex += 1
} else {
orderedPile.append(rightPile[rightIndex])
rightIndex += 1
}
}
return orderedPile
}
func mergeSortBottomUp<T>(_ a: [T], _ isOrderedBefore: (T, T) -> Bool) -> [T] {
let n = a.count
var z = [a, a] // the two working arrays
var d = 0 // z[d] is used for reading, z[1 - d] for writing
var width = 1
while width < n {
var i = 0
while i < n {
var j = i
var l = i
var r = i + width
let lmax = min(l + width, n)
let rmax = min(r + width, n)
while l < lmax && r < rmax {
if isOrderedBefore(z[d][l], z[d][r]) {
z[1 - d][j] = z[d][l]
l += 1
} else {
z[1 - d][j] = z[d][r]
r += 1
}
j += 1
}
while l < lmax {
z[1 - d][j] = z[d][l]
j += 1
l += 1
}
while r < rmax {
z[1 - d][j] = z[d][r]
j += 1
r += 1
}
i += width*2
}
width *= 2 // in each step, the subarray to merge becomes larger
d = 1 - d // swap active array
}
return z[d]
}