-
Notifications
You must be signed in to change notification settings - Fork 109
/
MergeSort.kt
140 lines (116 loc) · 3.22 KB
/
MergeSort.kt
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package sorting
/**
*
* Merge sort is a divide-and-conquer algorithm that was invented by John von Neumann in 1945
*
* Conceptually, a merge sort works as follows:
*
* 1) Divide the unsorted list into n sublists, each containing one element (a list of one element is considered sorted).
*
* 2) Repeatedly merge sublists to produce new sorted sublists until there is only one sublist remaining.
* This will be the sorted list.
*
*/
class MergeSort {
/**
* worst time: n * log(n)
* best time: n * log(n)
* average time: n * log(n)
*
* amount of memory: n
*/
fun <T : Comparable<T>> sort(array: Array<T>) {
val arraySize = array.size
val temporaryArray = array.copyOf()
var windowSize = 1
while (windowSize < arraySize) {
var left = 0
while (left + windowSize < arraySize) {
val middle = left + windowSize
var right = middle + windowSize
if (right > arraySize) right = arraySize
var i = left
var k = left
var j = middle
while (i < middle && j < right) {
if (array[i] <= array[j]) {
temporaryArray[k] = array[i]
i++
} else {
temporaryArray[k] = array[j]
j++
}
k++
}
while (i < middle) {
temporaryArray[k] = array[i]
i++
k++
}
while (j < right) {
temporaryArray[k] = array[j]
j++
k++
}
i = left
while (i < right) {
array[i] = temporaryArray[i]
i++
}
left += windowSize * 2
}
windowSize *= 2
}
}
/**
* worst time: n * log(n)
* best time: n * log(n)
* average time: n * log(n)
*
* amount of memory: n * log(n)
*/
fun sortRecursive(array: Array<Int>) {
val arraySize = array.size
if (arraySize < 2)
return
val middle = arraySize / 2
val left = Array(middle) { 0 }
val right = Array(arraySize - middle) { 0 }
var i = 0
while (i < middle) {
left[i] = array[i]
i++
}
while (i < arraySize) {
right[i - middle] = array[i]
i++
}
sortRecursive(left)
sortRecursive(right)
val leftSize = left.size
val rightSize = right.size
i = 0
var j = 0
var k = 0
while (i < leftSize && j < rightSize) {
if (left[i] <= right[j]) {
array[k] = left[i]
i++
} else {
array[k] = right[j]
j++
}
k++
}
while (i < leftSize) {
array[k] = left[i]
i++
k++
}
while (j < rightSize) {
array[k] = right[j]
j++
k++
}
}
}