Table of Contents
基数排序(Radix Sort)/ 桶排序(Bucket Sort)
使用Xcode Version 10.2 (10E125)
冒泡法(Bubble sort)
Runtime: O( N^2 ) average and worst case. Memory: O(1)
func bubbleSort<T: Comparable>(items: inout [T]) {
for i in 0...items.count-2 {
for j in 0...items.count-i-2 {
if items[j] > items[j+1] {
let tmp = items[j]
items[j] = items[j+1]
items[j+1] = tmp
}
}
}
}
选择排序(Selection Sort)
Runtime: O( n^2 ) average and worst case. Memory: O(1)
最直白的想法,找到最小的,换到最前面
func selectionSort<T: Comparable>(items: inout [T]) {
for i in 0...items.count-2 {
let rem = Array(items[i...items.count-1])
let indexOfMinimum = indexOfMin(items: rem) + i
if indexOfMinimum != i {
let tmp = items[indexOfMinimum]
items[indexOfMinimum] = items[i]
items[i] = tmp
}
}
}
func indexOfMin<T: Comparable>(items: [T]) -> Int {
var ret = 0
for i in 1..<items.count {
if items[ret] > items[i] {
ret = i
}
}
return ret
}
归并排序(Merge Sort)
Runtime: O(n log ( n)) average and worst case. Memory: Depends
递归,分两半,分别sort,merge
func mergeSort<T: Comparable>(items: inout [T]) {
if items.count <= 1 { return }
var helper = items
mergeSort2(items: &items, helper: &helper, start: 0, end:items.count-1)
}
func mergeSort2<T: Comparable>(items: inout [T],
helper: inout [T],
start: Int, end: Int) {
if start < end {
let middle = (start + end) / 2
mergeSort2(items: &items, helper: &helper, start: start, end: middle)
mergeSort2(items: &items, helper: &helper, start: middle+1, end: end)
merge(items: &items, helper: &helper, start: start, middle: middle, end: end)
}
}
func merge<T: Comparable>(items: inout [T],
helper: inout [T],
start: Int, middle: Int, end: Int) {
helper[start...end] = items[start...end]
var cur = start, curLeft = start, curRight = middle + 1
while curLeft <= middle && curRight <= end {
if helper[curLeft] <= helper[curRight] {
items[cur] = helper[curLeft]
curLeft += 1
} else {
items[cur] = helper[curRight]
curRight += 1
}
cur += 1
}
if curLeft <= middle {
items[cur...end] = helper[curLeft...middle]
}
}
快速排序(Quick Sort)
Runtime: O(nlog(n)) average, O(n^2) worst case. Memory: O(log(n))
随机一个element,小的放它前面,大的放它后面,然后再递归处理两边
func quickSort<T: Comparable>(items: inout [T]) {
quickSort2(items: &items, start: 0, end: items.count-1)
}
func quickSort2<T: Comparable>(items: inout [T], start: Int, end: Int) {
if start < end {
var pivotPos = (start + end) / 2
let pivot = items[pivotPos]
var left = start
var right = end
while left < right {
while items[right] >= pivot && right > left { right -= 1 }
while items[left] <= pivot && left < right { left += 1 }
if left < right {
items.swapAt(left, right)
}
}
if left < pivotPos && items[left] > pivot {
items.swapAt(pivotPos, left)
pivotPos = left
} else if left+1 < pivotPos && items[left+1] >= pivot {
items.swapAt(pivotPos, left+1)
pivotPos = left+1
} else if left > pivotPos && items[left] < pivot {
items.swapAt(pivotPos, left)
pivotPos = left
}
quickSort2(items: &items, start: start, end: pivotPos-1)
quickSort2(items: &items, start: pivotPos+1, end: end)
}
}
注意right和left的2个while语句,不能交换顺序,如果非要换,swap pivot的代码也得变
基数排序(Radix Sort)/ 桶排序(Bucket Sort)
Runtime: O(kn)
func radixSort(items: inout [Int]) {
var buckets = Dictionary<Int, Int>()
for item in items {
if let curVal = buckets[item] {
buckets[item] = curVal + 1
} else {
buckets[item] = 1
}
}
let sortedKeys = buckets.keys.sorted()
var curIndex = 0
for key in sortedKeys {
if let count = buckets[key] {
for _ in 1...count {
items[curIndex] = key
curIndex += 1
}
}
}
}