GO排序算法

一、快速排序

1.1 特点

  • 最好时间复杂度O(nlogn)
  • 平均时间复杂度O(nlogn)
  • 最坏时间复杂度O(n^2)
  • 空间复杂度O(nlogn)
  • 不稳定的排序算法
  • 适用于元素个数n较大的情况

1.2 问题

  • 排序的稳定性?
    排序算法的稳定是指当存在一样的元素时,排序前后元素的顺序不变
  • 为什么快速排序不稳定?
    比如切片[]int{ 5, 6, 6, 1, 1 },使用快排排序后,两个1的位置顺序发生了变化

1.3 实现

func QuickSort(a []int, low, high int) {
    if low < high {
        index := low + 1
        for i := index; i <= high; i++ {
            if a[i] < a[low] {
                a[i], a[index] = a[index], a[i]
                index++
            }
        }
        a[low], a[index - 1] = a[index - 1], a[low]
        QuickSort(a, low, index - 2)
        QuickSort(a, index, high)
    }
}

二、插入排序

2.1 特点

  • 最好时间复杂度O(n)
  • 平均时间复杂度O(n^2)
  • 最坏时间复杂度O(n^2)
  • 空间复杂度O(1)
  • 稳定的排序算法
  • 适用于元素本身有较好排序的情况

1.2 实现

func InsertionSort(a []int) {
    for i := 1; i < len(a); i++ {
        for j := i; j > 0 && a[j] < a[j - 1]; j-- {
            a[j], a[j - 1] = a[j - 1], a[j]
        }
    }
}

三、堆排序

2.1 特点

  • 最好时间复杂度O(nlogn)
  • 平均时间复杂度O(nlogn)
  • 最坏时间复杂度O(nlogn)
  • 空间复杂度O(1)
  • 不稳定的排序算法
  • 适用于元素较多的情况

1.2 实现

func HeapSort(arr []int) {
	size := len(arr)
	// 构建最大堆
	for i := size / 2; i >= 0; i-- {
		buildHeap(arr, i, size)
	}
	// 将最大堆的root节点值移动至末尾,剩余元素继续构建最大堆
	for i := len(arr) - 1; i > 0; i-- {
		size--
		arr[0], arr[i] = arr[i], arr[0]
		buildHeap(arr, 0, size)
	}
}

func buildHeap(arr []int, i int, size int) {
	left := 2 * i + 1
	right := 2 * i + 2
	largest := i
	if left < size && arr[left] > arr[largest] {
		largest = left
	}
	if right < size && arr[right] > arr[largest] {
		largest = right
	}
	if largest != i {
		arr[i], arr[largest] = arr[largest], arr[i]
		buildHeap(arr, largest, size)
	}
}
posted @ 2021-12-10 14:59  自然_卷  阅读(77)  评论(0)    收藏  举报