[ GO基础排序算法 | 青训营笔记 ]

60 阅读1分钟

1. 插入排序:

算法步骤
  • 从索引为1的位置开始遍历(索引为0的数视作已排序)
  • 取出当前索引的数,从当前索引减一开始从后往前内层遍历
  • 如果当前内层遍历的数大于当前索引的数,将该元素后移一个位置
  • 直到找到小于当前索引的位置,结束内存循环
  • 将当前处理数拆入找到的位置,处理下一个数。
代码实现
/*  
插入排序  
*/  
func InsertSort(nums []int) {  
    for i := 1; i < len(nums); i++ {  
        var j = i - 1  
        var n = nums[i]  
        for j >= 0 && n < nums[j] {  
            nums[j+1] = nums[j]  
            j--  
        }  
        nums[j+1] = n  
    }  
}
时间复杂度

最佳:O(n) ,最差:O(n^2), 平均:O(n^2)

2.快速排序:

算法步骤
  • 分治处理,与归并排序相比,不再平分数组,每次选择一个中心元,将比其小的放在数组左边,比其大的放在数组右边
  • 然后递归处理其中心元左侧的数组和右侧的数组。
  • 在处理某些特殊分布的数组时,中心元的选择会影响算法的时间复杂度。中心元的选择:1.选择第一个或最后一个元素;2.随机选择;3三数取中(即选取第一个、最后一个以及中间的元素中的中位数)
代码实现
func swap(nums []int, i int, j int) {  
    var t = (nums)[i]  
    (nums)[i] = (nums)[j]  
    (nums)[j] = t  
}  
  
/*  
*  
快速排序,选择首元素作为pivot  
*/  
func QuickSort(nums []int) {  
    quickSortPartition(nums, 0, len(nums)-1)  
}  
  
// 选择首元素作为pivot  
func getPosition(nums []int, start int, end int) int {  
    var pivot = (nums)[start]  
    var pointer = start + 1  
    for i := start + 1; i <= end; i++ {  
        if (nums)[i] <= pivot {  
        swap(nums, pointer, i)  
        pointer++  
        }  
    }  
    (nums)[start] = (nums)[pointer-1]  
    (nums)[pointer-1] = pivot  
    return pointer - 1  
}  
  
func quickSortPartition(nums []int, start int, end int) {  
    if start < end {  
        var position = getPosition(nums, start, end)  
        quickSortPartition(nums, start, position-1)  
        quickSortPartition(nums, position+1, end)  
    }  
}
时间复杂度

最佳:O(nlogn) ,最差:O(n^2), 平均:O(nlogn)

3.堆排序:

  • 堆排序的过程是一个不断建堆的过程,关键在于堆化函数的实现。
  • 堆在逻辑上表示为一个二叉树,每个节点的值都大于或小于左子孩子和右子孩子的值。实际上堆可以使用一维数组表示,从索引0开始,具有孩子节点的节点索引的最大值为len(nums)/2 -1,其左子孩子的索引为2*i +1,其右子孩子的索引值为2*i +2
算法步骤
  • 将初始待排序列构建成大顶堆
  • 交换堆顶元素和堆中最后一个元素,此时堆长度之后的序列为有序序列
  • 对堆顶元素重新开始堆化过程
  • 重复直到所有元素都有序
算法步骤
func heapfy(nums []int, index int, heapSize int) {  
    var left = index*2 + 1  
    var right = index*2 + 2  
    var maxNum = nums[index]  
    var maxIndex = index  
    if left <= heapSize && nums[left] > maxNum {  
    maxNum = nums[left]  
    maxIndex = left  
    }  
    if right <= heapSize && nums[right] > maxNum {  
        maxNum = nums[right]  
        maxIndex = right  
    }  
    if maxIndex != index {  
        swap(nums, index, maxIndex)  
        heapfy(nums, maxIndex, heapSize)  
    }  
}  
  
func HeapSort(nums []int) {  
    for i := len(nums)/2 - 1; i >= 0; i-- {  
        heapfy(nums, i, len(nums)-1)  
    }  
    var heapSize = len(nums) - 1  
    for i := 0; i < len(nums); i++ {  
        swap(nums, 0, heapSize)  
        heapSize--  
        heapfy(nums, 0, heapSize)  
    }  
}
时间复杂度

最佳:O(nlogn) ,最差:O(nlogn), 平均:O(nlogn)