一、基本排序算法
Golang提供了多种基本排序算法,最常用的有冒泡排序、插入排序和选择排序。三种算法的主要区别在于排序的稳定性、时间复杂度和空间复杂度。
1. 冒泡排序
func BubbleSort(data sort.Interface) {
for i := 0; i < data.Len()-1; i++ {
for j := 0; j < data.Len()-1-i; j++ {
if data.Less(j+1, j) {
data.Swap(j, j+1)
}
}
}
}
冒泡排序是一种基本的排序算法,它相邻的元素进行比较,如果满足条件则交换位置。该算法的时间复杂度为O(n^2)。
2. 插入排序
func InsertionSort(data sort.Interface) {
for i := 1; i 0 && data.Less(j, j-1); j-- {
data.Swap(j, j-1)
}
}
}
插入排序是一种比较稳定的排序算法,它将数组分为已排序和未排序两部分,每次从未排序的元素中选择一个插入到已排序的元素中。该算法的时间复杂度为O(n^2)。
3. 选择排序
func SelectionSort(data sort.Interface) {
for i := 0; i < data.Len()-1; i++ {
minIndex := i
for j := i + 1; j < data.Len(); j++ {
if data.Less(j, minIndex) {
minIndex = j
}
}
if minIndex != i {
data.Swap(i, minIndex)
}
}
}
选择排序是一种比较简单的排序算法,它每次选择最小的元素放到已排序的元素中。该算法的时间复杂度为O(n^2)。
二、快速排序
快速排序是一种比较常用的排序算法,它的时间复杂度为O(nlogn)。该算法利用分治的思想,将一个大问题分成多个小问题解决,然后将小问题的结构合并起来。
func QuickSort(data sort.Interface) {
quickSort(data, 0, data.Len()-1)
}
func quickSort(data sort.Interface, left, right int) {
if left >= right {
return
}
pivotIndex := partition(data, left, right)
quickSort(data, left, pivotIndex-1)
quickSort(data, pivotIndex+1, right)
}
func partition(data sort.Interface, left, right int) int {
pivotIndex := left
pivot := right
for i := left; i < right; i++ {
if data.Less(i, pivot) {
data.Swap(i, pivotIndex)
pivotIndex++
}
}
data.Swap(pivotIndex, right)
return pivotIndex
}
快速排序的主要思想是选择一个基准值(通常是数组的最后一个值),将数组分为两部分,一部分小于基准值,一部分大于基准值,然后按照同样的方式递归处理两部分的子数组,直到排序完成。
三、归并排序
归并排序是一种比较高效的排序算法,它的时间复杂度为O(nlogn)。该算法利用分治的思想,将一个大问题分成多个小问题解决,然后将小问题的结构合并起来。
func MergeSort(data sort.Interface) {
mergeSort(data, 0, data.Len()-1)
}
func mergeSort(data sort.Interface, left, right int) {
if left >= right {
return
}
mid := (left + right) / 2
mergeSort(data, left, mid)
mergeSort(data, mid+1, right)
merge(data, left, mid, right)
}
func merge(data sort.Interface, left, mid, right int) {
tmp := make([]reflect.Value, right-left+1)
i, j, k := left, mid+1, 0
for i <= mid && j <= right {
if data.Less(i, j) {
tmp[k] = data.Index(i)
i++
} else {
tmp[k] = data.Index(j)
j++
}
k++
}
for i <= mid {
tmp[k] = data.Index(i)
k++
i++
}
for j <= right {
tmp[k] = data.Index(j)
k++
j++
}
for i, j := left, 0; i <= right; i, j = i+1, j+1 {
data.Swap(i, reflect.Indirect(tmp[j]).Interface().(int))
}
}
归并排序将数组分成两部分,分别排序,然后再将两个有序数组合并成一个有序数组。该算法需要额外的内存空间存储数组的拷贝,因此空间复杂度为O(n)。
四、堆排序
堆排序是一种比较常用的排序算法,它的时间复杂度为O(nlogn)。该算法利用堆的性质来实现排序。
func HeapSort(data sort.Interface) {
heap := &Heap{data}
heap.Init()
for i := data.Len() - 1; i >= 0; i-- {
heap.data.Swap(0, i)
heap.size--
heap.down(0)
}
}
type Heap struct {
data sort.Interface
size int
}
func (h *Heap) Init() {
h.size = h.data.Len()
for i := h.size/2 - 1; i >= 0; i-- {
h.down(i)
}
}
func (h *Heap) down(root int) {
for {
left := root*2 + 1
if left >= h.size {
break
}
right := left + 1
maxChildIndex := left
if right < h.size && h.data.Less(left, right) {
maxChildIndex = right
}
if h.data.Less(root, maxChildIndex) {
h.data.Swap(root, maxChildIndex)
root = maxChildIndex
} else {
break
}
}
}
堆是一种数据结构,它可以很方便地实现排序。堆排序分为两个阶段,第一阶段是建立一个最大堆,第二阶段是依次取出堆顶元素,并将剩余元素重新构建一个最大堆。
五、小结
本文介绍了Golang中的排序算法,包括冒泡排序、插入排序、选择排序、快速排序、归并排序和堆排序。每种算法的时间复杂度和空间复杂度各有不同,开发者应该根据实际情况选择最合适的算法。
原创文章,作者:SAFO,如若转载,请注明出处:https://www.506064.com/n/131792.html