Go 1.19 排序算法实践|青训营笔记

103 阅读2分钟

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)