以前经常看到各种排序算法,今天也对以下6种排序算法的时间性能做了一次测试: 测试代码地址
1. 冒泡排序 O(n^2)
/**
冒泡排序
@Param {[]int} arr 整形切片
*/
func BubbleSort(arr []int) {
length := len(arr)
for i := 0; i < length; i++ {
for j := 0; j < length-i-1; j++ {
if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
复制代码
2. 插入排序 O(n^2)
/**
插入排序
@Param {[]int} arr 整形切片
*/
func InsertSort(arr []int) {
length := len(arr)
for i := 1; i < length; i++ {
for j := i; j > 0 && arr[j] < arr[j-1]; j-- {
arr[j], arr[j-1] = arr[j-1], arr[j]
}
}
}
复制代码
3. 选择排序 O(n^2)
/**
选择排序
@Param {[]int} arr 整形切片
*/
func SelectSort(arr []int) {
length := len(arr)
for i := 0; i < length-1; i++ {
index := i
for j := i + 1; j < length; j++ {
if arr[index] > arr[j] {
index = j
}
}
if index != i {
arr[i], arr[index] = arr[index], arr[i]
}
}
}
复制代码
4. 希尔排序 O(nlogn)
/**
希尔排序 O(nlogn)
@Param {[]int} arr 整形切片
*/
func ShellSort(arr []int) {
length := len(arr)
for fraction := length / 2; fraction > 0; fraction /= 2 {
for i := fraction; i < length; i++ {
for j := i - fraction; j >= 0 && arr[j] > arr[j+fraction]; j -= fraction {
arr[j], arr[j+fraction] = arr[j+fraction], arr[j]
}
}
}
}
复制代码
5. 快速排序 :O(nlogn)期望时间,O(n^2)最坏情况;对于大的、随机数列表一般相信是最快的已知排序
/**
快速排序
@Param {[]int} arr 整形切片
*/
func QuickSort(arr []int, low, high int) {
if low >= high {
return
}
first, last := low, high
key := arr[first]
for first < last {
for first < last && arr[last] >= key {
last--
}
arr[first] = arr[last]
for first < last && arr[first] <= key {
first++
}
arr[last] = arr[first]
}
arr[first] = key
QuickSort(arr, low, first-1)
QuickSort(arr, first+1, high)
}
复制代码
6. 堆排序 O(nlogn)
/**
堆排序 O(nlogn)
@Param {[]int} arr 整形切片
*/
func HeapSort(arr []int) {
// 切片长度
length := len(arr)
for i := length/2 - 1; i >= 0; i-- {
Sort(arr, i, length)
}
for i := length - 1; i >= 0; i-- {
arr[0], arr[i] = arr[i], arr[0]
Sort(arr, 0, i)
}
}
func Sort(arr []int, start, end int) {
dad := start
son := dad*2 + 1
if son >= end {
return
}
if son+1 < end && arr[son] < arr[son+1] {
son++
}
if arr[son] > arr[dad] {
arr[son], arr[dad] = arr[dad], arr[son]
Sort(arr, son, end)
}
}
复制代码
7.归并排序 O(n log n)
/**
归并排序 O(n log n)
@Param {[]int} arr 整形切片
*/
func MergeSort(arr []int) []int {
length := len(arr)
if length <= 1 {
return arr
}
mid := length / 2
l := MergeSort(arr[:mid])
r := MergeSort(arr[mid:])
return Merge(l, r)
}
func Merge(left, right []int) (result []int) {
l, r := 0, 0 // 左右两切片的下标
for l < len(left) && r < len(right) {
if left[l] < right[r] {
result = append(result, left[l])
l++
} else {
result = append(result, right[r])
r++
}
}
result = append(result, left[l:]...)
result = append(result, right[r:]...)
return
}
复制代码
测试过程: 统计时间 = 产生随机数时间 + 排序时间
- 产生10万随机数排序结果如下图:
- 产生20万随机数排序结果如下图:
- 产生1000万随机数排序结果如下图:
总结:
1. 在随机数情况下,表现最差的是冒泡,表现最好的是快速排序
2. 在随机数1000万的时候。冒泡排序、插入排序和选择排序排序时间未知。等了好几分钟都没有结果。快速排序表现最好。
复制代码
总得来说,在随机序列的情况,快速排序表现最好