Go 1.19 排序算法实践
引言
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。这里记录三种排序:插入排序、快速排序和堆排序。
插入排序
插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中。
func InsertionSort(array []int) []int {
if len(array) <= 1 {
return array
}
for i := 1; i < len(array); i++ {
value := array[i]
j := i - 1
for ; j >= 0; j-- {
if value < array[j] {
array[j+1] = array[j]
} else {
break
}
}
array[j+1] = value
}
return array
}
func main() {
array := []int{397, 52, 55, 253, 574, 112, 778, 4, 445, 400}
array = InsertionSort(array)
for i, v := range array {
fmt.Printf("下标为%d的值为%d", i, v)
fmt.Println()
}
}
快速排序
快速排序是从冒泡排序演变而来的算法,但是比冒泡排序要高效得多,所以叫做快速排序。快速排序之所以快速,是因为它使用了“分治法”。 和冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。不同的是,冒泡排序在每一轮只把一个元素移动到数列的一端,而快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。
func QuickSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
splitdata := arr[0] //第一个数据为基准
low := make([]int, 0, 0) //比我小的数据
hight := make([]int, 0, 0) //比我大的数据
mid := make([]int, 0, 0) //与我一样大的数据
mid = append(mid, splitdata) //加入一个
for i := 1; i < len(arr); i++ {
if arr[i] < splitdata {
low = append(low, arr[i])
} else if arr[i] > splitdata {
hight = append(hight, arr[i])
} else {
mid = append(mid, arr[i])
}
}
low, hight = QuickSort(low), QuickSort(hight) //切割递归处理
myarr := append(append(low, mid...), hight...)
return myarr
}
//快读排序算法
func main() {
arr := []int{1, 9, 10, 30, 2, 5, 45, 8, 63, 234, 12}
fmt.Println(QuickSort(arr))
}
堆排序
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,是不稳定排序。
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
三种算法分析
- 插入排序在短序列中速度最快
- 快速排序在其他情况中速度最快
- 堆排序时间复杂度为O(nlogn)