一、快速排序
1.1 特点
- 最好时间复杂度O(nlogn)
- 平均时间复杂度O(nlogn)
- 最坏时间复杂度O(n^2)
- 空间复杂度O(nlogn)
- 不稳定的排序算法
- 适用于元素个数n较大的情况
1.2 问题
- 排序的稳定性?
排序算法的稳定是指当存在一样的元素时,排序前后元素的顺序不变
- 为什么快速排序不稳定?
比如切片[]int{ 5, 6, 6, 1, 1 },使用快排排序后,两个1的位置顺序发生了变化
1.3 实现
func QuickSort(a []int, low, high int) {
if low < high {
index := low + 1
for i := index; i <= high; i++ {
if a[i] < a[low] {
a[i], a[index] = a[index], a[i]
index++
}
}
a[low], a[index - 1] = a[index - 1], a[low]
QuickSort(a, low, index - 2)
QuickSort(a, index, high)
}
}
二、插入排序
2.1 特点
- 最好时间复杂度O(n)
- 平均时间复杂度O(n^2)
- 最坏时间复杂度O(n^2)
- 空间复杂度O(1)
- 稳定的排序算法
- 适用于元素本身有较好排序的情况
1.2 实现
func InsertionSort(a []int) {
for i := 1; i < len(a); i++ {
for j := i; j > 0 && a[j] < a[j - 1]; j-- {
a[j], a[j - 1] = a[j - 1], a[j]
}
}
}
三、堆排序
2.1 特点
- 最好时间复杂度O(nlogn)
- 平均时间复杂度O(nlogn)
- 最坏时间复杂度O(nlogn)
- 空间复杂度O(1)
- 不稳定的排序算法
- 适用于元素较多的情况
1.2 实现
func HeapSort(arr []int) {
size := len(arr)
// 构建最大堆
for i := size / 2; i >= 0; i-- {
buildHeap(arr, i, size)
}
// 将最大堆的root节点值移动至末尾,剩余元素继续构建最大堆
for i := len(arr) - 1; i > 0; i-- {
size--
arr[0], arr[i] = arr[i], arr[0]
buildHeap(arr, 0, size)
}
}
func buildHeap(arr []int, i int, size int) {
left := 2 * i + 1
right := 2 * i + 2
largest := i
if left < size && arr[left] > arr[largest] {
largest = left
}
if right < size && arr[right] > arr[largest] {
largest = right
}
if largest != i {
arr[i], arr[largest] = arr[largest], arr[i]
buildHeap(arr, largest, size)
}
}