常见排序算法包括冒泡、选择、插入、快排、归并、等,其中快排为官方包sort的默认排序方式,那我们先来看一下官方快拍实现方式吧:

func quickSort(data Interface, a, b, maxDepth int) {
	for b-a > 12 { // Use ShellSort for slices <= 12 elements
		if maxDepth == 0 {
			heapSort(data, a, b)
			return
		}
		maxDepth--
		mlo, mhi := doPivot(data, a, b)
		// Avoiding recursion on the larger subproblem guarantees
		// a stack depth of at most lg(b-a).
		if mlo-a < b-mhi {
			quickSort(data, a, mlo, maxDepth)
			a = mhi // i.e., quickSort(data, mhi, b)
		} else {
			quickSort(data, mhi, b, maxDepth)
			b = mlo // i.e., quickSort(data, a, mlo)
		}
	}
	if b-a > 1 {
		// Do ShellSort pass with gap 6
		// It could be written in this simplified form cause b-a <= 12
		for i := a + 6; i < b; i++ {
			if data.Less(i, i-6) {
				data.Swap(i, i-6)
			}
		}
		insertionSort(data, a, b)
	}
}

首先他区分了我们数组大小,如果小于12的话他会以6位分割点依次去对比前后两部分的大小,如果i小于i-6则交换(从小到达排序)这部分源码展示:

然后会使用插入排序的方式进行排序输出

如果数组长度大于12的话进行执行doPivot方法及下边方式进行数据分割迭代排序。

这里我们自己也实现了一些简单方式的排序代码:

主函数代码展示:

package main

import (
	"fmt"
	"math/rand"
	"sort"
	"sortmain/adjustheapSort"
	"time"
)

const (
	num = 10000        //测试数组长度
	rangeNum = 100000  //数组元素大小范围
)

func GenerateRand() []int {
	randSeed := rand.New(rand.NewSource(time.Now().Unix()+time.Now().UnixNano()))
	arr := make([]int,num)
	for i :=0;i<num;i++{
		arr[i] = randSeed.Intn(rangeNum)
	}
	return arr
}

func IsSame(slice1, slice2 []int) bool {
	if len(slice1) != len(slice2) {
		return false
	}
	if (slice1 == nil) != (slice2 ==nil) {
		return false
	}
	for i, num := range slice1{
		if num != slice2[i] {
			return false
		}
	}
	return true
}

func main() {
	arr := GenerateRand()
	org_arr := make([]int,num)
	copy(org_arr,arr)
	//冒泡排序
	//bubbleSort.BubbleSort(arr)
	//选择排序
	//selectSort.SelectSort(arr)
	//插入排序
	//insertSort.InsertSort(arr)
	//快排
	//quickSort.QuickSort(arr,0,len(arr)-1)
	//归并排序
	//mergeSort.MergeSort(arr,0,len(arr)-1)
	//堆排序
	adjustheapSort.HeapSort(arr)
	sort.Ints(org_arr)
	fmt.Println(arr[:15],org_arr[:15],IsSame(arr,org_arr))
}

冒泡排序代码:

package bubbleSort

//冒泡排序:
//通过对序列从后往前,依次比较相邻元素的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后向前移动。


func BubbleSort(arr []int) {
	lenArr := len(arr)
	for i:=0;i<lenArr-1;i++ {
		for j:=0;j<lenArr-i-1;j++ {
			if (arr)[j] > (arr)[j+1] {
				(arr)[j],(arr)[j+1] = (arr)[j+1],(arr)[j]
			}
		}
	}
}

选择排序代码:

package selectSort

func SelectSort(arr []int)  {
	for i :=0;i<len(arr)-1;i++ {
		for j :=i+1; j<=len(arr)-1;j++{
			if (arr)[j] < (arr)[i] {
				(arr)[j],(arr)[i] = (arr)[i],(arr)[j]
			}
		}
	}
}

插入排序代码:

package insertSort

func InsertSort(arr []int)  {
	for i := 1;i<len(arr)-1;i++{
		for j:=i;j>0;j-- {
			if arr[j-1] >arr[j] {
				arr[j-1],arr[j] = arr[j],arr[j-1]
			}
		}
	}
}

快速排序代码:

package quickSort

//快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,
//其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,
//整个排序过程可以递归进行,以此达到整个数据变成有序序列。

func QuickSort(arr []int, first, last int) {
	flag := first
	left := first
	right := last
	if first >= last {
		return
	}
	// 将大于arr[flag]的都放在右边,小于的,都放在左边
	for first < last {
		// 如果flag从左边开始,那么是必须先从有右边开始比较,也就是先在右边找比flag小的
		for first < last {
			if arr[last] >= arr[flag] {
				last--
				continue
			}
			// 交换数据
			arr[last], arr[flag] = arr[flag], arr[last]
			flag = last
			break
		}
		for first < last {
			if arr[first] <= arr[flag] {
				first++
				continue
			}
			arr[first], arr[flag] = arr[flag], arr[first]
			flag = first
			break
		}
	}
	QuickSort(arr, left, flag-1)
	QuickSort(arr, flag+1, right)
}

归并排序代码:

package mergeSort

//合并
func Merge(arr []int, l, mid, r int) {
	// 分别复制左右子数组
	n1, n2 := mid-l+1, r-mid
	left, right := make([]int, n1), make([]int, n2)
	copy(left, arr[l:mid+1])
	copy(right, arr[mid+1:r+1])
	i, j := 0, 0
	k := l
	for; i < n1 && j < n2; k++ {
		if left[i] <= right[j] {
			arr[k] = left[i]
			i++
		} else {
			arr[k] = right[j]
			j++
		}
	}
	for; i < n1; i++ {
		arr[k] = left[i]
		k++
	}
	for; j < n2; j++ {
		arr[k] = right[j]
		k++
	}
}

//分治
func MergeSort(arr []int, l, r int) {
	if l < r {
		mid := (l + r - 1) / 2
		MergeSort(arr, l, mid)
		MergeSort(arr, mid+1, r)
		Merge(arr, l, mid, r)
	}
}
堆排序代码:
package adjustheapSort

//堆调整
func adjust_heap(arr []int, i, size int) {
	if i <= (size-2)/2 {
		//左右子节点
		l, r := 2*i+1, 2*i+2
		m := i
		if l < size && arr[l] > arr[m] {
			m = l
		}
		if r < size && arr[r] > arr[m] {
			m = r
		}
		if m != i {
			arr[m], arr[i] = arr[i], arr[m]
			adjust_heap(arr, m, size)
		}
	}
}

//建堆
func build_heap(arr []int) {
	size := len(arr)
	//从最后一个子节点开始向前调整
	for i := (size - 2) / 2; i >= 0; i-- {
		adjust_heap(arr, i, size)
	}
}

func HeapSort(arr []int) {
	size := len(arr)
	build_heap(arr)
	for i := size - 1; i > 0; i-- {
		//顶部arr[0]为当前最大值,调整到数组末尾
		arr[0], arr[i] = arr[i], arr[0]
		adjust_heap(arr, 0, i)
	}
}