github: https://github.com/intbird/sort-algorithms-kotlin
0.元素交换
临时空间
fun swrap(array: IntArray, index1: Int, index2: Int) {
val temp = array[index2]
array[index2] = array[index1]
array[index1] = temp
}
自身加减
fun swrapInt(array: IntArray, index1: Int, index2: Int) {
array[index1] = array[index1] + array[index2] // 求和
array[index2] = array[index1] - array[index2] // 得差(减数1 = 和 - 减数2)
array[index1] = array[index1] - array[index2] // 得差(减数2 = 和 - 减数1)
}
1.选择排序
依次选出数组中最小的元素后放在最前面
fun sort1(array: IntArray) {
for (i in 0 until array.size - 1) { // 第一小组循环
var minIndex = i // 假定当前为最小值
val next = (i + 1) // 循环向后比较
for (j in next until array.size) { //第二小组循环
if (array[j] < array[minIndex]) { //当前小组内 后一个值比前一个小
minIndex = j // 重新设置组内最小值
}
}
if (minIndex != i) { // 最小值已变
ArrayUtils.swrap(array, i, minIndex) //交换
}
}
}
2.冒泡排序
两两相比,大的都往后放
fun sort2(array: IntArray) {
val size = array.size
for (i in 0..size) {
for (j in 0 until size - i - 1) { // 第i次循环后, [i-size]区间已有序
if (array[j] > array[j+1]) { // 前一个比后一个大,则交换
ArrayUtils.swrap(array, j, j+1)
}
print("${array[j]}, ${array[j+1]}\t")
}
println()
}
}
3.插入排序
相当于头部有一个新队列
每次有新数据过来时,
从后向前调整新数据在有序队列的位置
fun sort3(array: IntArray) {
val size = array.size
for (i in 1 until size) {
var j = i
// 新队列只有一个数时需要判空
// 新队列的后一个比前一个小则交换
while (j > 0 && array[j] < array[j - 1]) {
ArrayUtils.swrap(array, j, j - 1)
j--
}
}
}
4.归并排序
分,治
fun sort4(array: IntArray) {
val tempArray = array.clone()
merge(array, tempArray, 0, array.size - 1)
}
fun merge(array: IntArray, tempArray: IntArray, left: Int, right: Int) {
// 再分就没了
if (left < right) {
val mid = (left + right) / 2
// 分左侧
merge(array, tempArray, left, mid)
// 分右侧
merge(array, tempArray, mid + 1, right)
// 合并有序
sort4Internal(array, tempArray, left, mid, right)
}
}
fun sort4Internal(array: IntArray, tempArray: IntArray, left: Int, mid: Int, right: Int) {
var start1 = left
var start2 = mid + 1
var k = 0
while (start1 <= mid && start2 <= right) {
if (array[start1] < array[start2]) {
tempArray[k++] = array[start1++]
} else {
tempArray[k++] = array[start2++]
}
}
while (start1 <= mid) {
tempArray[k++] = array[start1++]
}
while (start2 <= right) {
tempArray[k++] = array[start2++]
}
for (x in 0 until k) {
array[left+x] = tempArray[x]
}
}
5.希尔排序
fun sort5(array: IntArray) {
var gap = 1
// 将数据分段后再应用插入排序
while (gap < array.size) {
gap = gap * 3 + 1
}
while (gap > 0) {
for (i in gap until array.size) {
val temp = array[i]
var j = i - gap // j 为最左侧数据
// 左边 > 右边,则进行交换
while (j >= 0 && array[j] > temp) {
array[j + gap] = array[j]
// 在一个小分组里面进行循环
j -= gap
}
array[j + gap] = temp
}
gap = floor(gap / 3.0f.toDouble()).toInt()
}
}
6.堆排序
fun sort6(array: IntArray) {
for (i in array.size / 2 downTo 0) {
adjustHeap(array, i, array.size)
}
for (j in array.size - 1 downTo 0) {
ArrayUtils.swrap(array, 0, j)
adjustHeap(array, 0, j)
}
}
fun adjustHeap(arr: IntArray, i: Int, length: Int) {
var i = i
val temp = arr[i]
var k = i * 2 + 1
while (k < length) {
if (k + 1 < length && arr[k] < arr[k + 1]) {
k++
}
if (arr[k] > temp) {
arr[i] = arr[k]
i = k
} else {
break
}
k = k * 2 + 1
}
arr[i] = temp
}
7. 快速排序
fun sort7(array: IntArray) {
quickSort(array, 0, array.size - 1)
}
fun quickSort(array: IntArray, left: Int, right: Int) {
if (left < right) {
val pivotIndex = getPartition1(array, left, right)
quickSort(array, left, pivotIndex - 1)
quickSort(array, pivotIndex + 1, right)
}
}
fun getPartition1(array: IntArray, left: Int, right: Int): Int {
val pivot = left
var start = pivot + 1
for (index in start..right) {
if (array[index] < array[pivot]) {
ArrayUtils.swrap(array, index, start)
start++
}
}
ArrayUtils.swrap(array, pivot,start - 1)
return start - 1
}
// 原地交互
fun getPartition2(array: IntArray, left: Int, right: Int): Int {
// 选定一个基准值
val pivot = left
val pivotValue = array[pivot]
// 把基准值移到末尾
ArrayUtils.swrap(array, pivot, right)
var newStart = pivot // 记录基准值后移变化
for (index in left until right) {
if (array[index] <= pivotValue) {
ArrayUtils.swrap(array, index, newStart)
// 位序后移
newStart++
}
}
// 基准值后移
ArrayUtils.swrap(array, newStart, right)
return newStart
}
Readme
// 1. selectSort 两次循环,选出最小值
// for ( i..length) {
// min // 发现最小值
// for (i +1 ..length)
// min // 发现最小值
// swap(min, i)
// 2. bubbleSort 大的靠后,最后n位有序
// for (i..length)
// for (j..length-n) // length-n = 0..n
// if j > j-1
// swap(j, j-1)
// 3. insertSort 最前n位有序,往前插入
// for (i..length)
// for (j i..0)
// if j < j-1
// swap(j, j-1)
// 4. mergeSort 分 + 治
// [0, 1, 2, 3, 4, 5, 6]
// (0,1) + (2,3) + (0 - 3) + | + (4,5) + (5,6) + (4 - 6)
// (0,3) - (4,6)
// 5. shellSort 转表发
// 13 14 94 33 82
// 25 59 94 65 23
// 45 27 73 25 39
// 10
//
// 10 14 13
// 25 23 33
// 27 25 59
// 39 65 73
// 45 94 82
// 94