提示:刷左神视频有感,B站视频链接:https://www.bilibili.com/video/BV13g41157hK
前言
好记性不如烂笔头,简单记录,方便以后回顾
针对几类排序算法的比较
一、比较图
时间复杂度 | 空间复杂度 | 稳定性 | |
---|---|---|---|
插入排序 | O(N^2) | O(1) | 稳定 |
希尔排序 | O(N^(1.3-2)) | O(1) | 稳定 |
归并排序 | O(N*logN) | O(N) | 稳定 |
快速排序 | O(N*logN) | O(logN) | 不稳定 |
堆排序 | O(N*logN) | O(1) | 不稳定 |
二、代码实现(golang)
1.插入排序
代码如下:
func InsertionSort(arr []int32) {
for i := 1; i < len(arr); i++ {
for j := i; j > 0; j-- {
if arr[j] < arr[j - 1] {
arr[j], arr[j - 1] = arr[j - 1], arr[j]
} else {
break
}
}
}
}
2.希尔排序
参照博客:https://blog.csdn.net/qq_37703224/article/details/121484909
代码如下:
func ShellSort(arr []int32) {
for step := len(arr) / 2; step >= 1; step /= 2 {
for i := step; i < len(arr); i += step {
for j := i; j > 0; j -= step {
if arr[j] < arr[j - step] {
arr[j], arr[j - step] = arr[j - step], arr[j]
} else {
break
}
}
}
}
}
3.归并排序
代码如下:
func MergeSort(arr []int32, left, right int32) []int32 {
if left >= right {
return arr
}
middle := left + (right - left) >> 1
MergeSort(arr, left, middle)
MergeSort(arr, middle + 1, right)
merge(arr, left, right, middle)
return arr
}
func merge(arr []int32, left, right, middle int32) {
var helpArr []int32
leftFlag := left
rightFlag := middle + 1
for leftFlag <= middle && rightFlag <= right {
if arr[leftFlag] <= arr[rightFlag] {
helpArr = append(helpArr, arr[leftFlag])
leftFlag += 1
} else {
helpArr = append(helpArr, arr[rightFlag])
rightFlag += 1
}
}
if leftFlag <= middle {
helpArr = append(helpArr, arr[leftFlag: middle+1]...)
}
if rightFlag <= right {
helpArr = append(helpArr, arr[rightFlag: right+1]...)
}
for i := 0; i < len(helpArr); i++ {
arr[int(left) + i] = helpArr[i]
}
}
4.快速排序
代码如下:
func QuickSort(arr []int32, left, right int32) []int32 {
if left >= right {
return arr
}
leftEndIndex, rightStartIndex := partition(arr, left, right)
QuickSort(arr, left, leftEndIndex)
QuickSort(arr, rightStartIndex, right)
return arr
}
func partition(arr []int32, left, right int32) (leftEndIndex, rightStartIndex int32) {
rand.Seed(time.Now().UnixNano())
flag := rand.Int31n(right - left) + left
flagNum := arr[flag]
leftEndIndex = left - 1
rightStartIndex = right + 1
for i := left; i < rightStartIndex; i++ {
if arr[i] < flagNum {
leftEndIndex++
arr[i], arr[leftEndIndex] = arr[leftEndIndex], arr[i]
} else if arr[i] > flagNum {
rightStartIndex--
arr[i], arr[rightStartIndex] = arr[rightStartIndex], arr[i]
i--
}
}
return leftEndIndex, rightStartIndex
}
5.堆排序
代码如下:
func HeapSort(arr []int32) {
if len(arr) <= 1 {
return
}
heapSize := int32(len(arr))
buildMaxHeap(arr, heapSize)
for heapSize > 0 {
arr[0], arr[heapSize - 1] = arr[heapSize - 1], arr[0]
heapSize--
heapify(arr, 0, heapSize)
}
}
func buildMaxHeap(arr []int32, heapSize int32) {
for i := heapSize - 1; i >= 0; i-- {
heapify(arr, i, heapSize)
}
}
func heapify(arr []int32, nodeIndex int32, heapSize int32) {
left := nodeIndex * 2 + 1
right := nodeIndex * 2 + 2
maxIndex := nodeIndex
if left < heapSize && arr[left] > arr[maxIndex] {
maxIndex = left
}
if right < heapSize && arr[right] > arr[maxIndex] {
maxIndex = right
}
if maxIndex != nodeIndex {
arr[maxIndex], arr[nodeIndex] = arr[nodeIndex], arr[maxIndex]
heapify(arr, maxIndex, heapSize)
}
}