基础排序算法总结(2) | 青训营笔记

81 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天

选择排序

选择排序是一种简单的排序算法,其基本思想是每次选择未排序部分中的最小值,将它与未排序部分的第一个元素交换位置,然后继续对剩余未排序部分进行选择排序,直到整个数组都有序。

func selectionSort(arr []int) {
    n := len(arr)
    for i := 0; i < n-1; i++ {
        minIndex := i
        for j := i + 1; j < n; j++ {
            if arr[j] < arr[minIndex] {
                minIndex = j
            }
        }
        // 交换arr[i]和arr[minIndex]的位置
        arr[i], arr[minIndex] = arr[minIndex], arr[i]
    }
}

在这个实现中,我们首先获取数组的长度,然后使用两个嵌套的for循环来遍历数组。外层循环从第一个元素开始遍历到倒数第二个元素,内层循环从外层循环的下一个元素开始遍历到最后一个元素。在内层循环中,我们找到未排序部分的最小值,然后将它与未排序部分的第一个元素交换位置。当外层循环结束时,整个数组都已经排好序。

选择排序是一种不稳定的排序算法,其时间复杂度为O(n^2)。由于每次交换位置都需要执行一次赋值操作,因此选择排序的性能通常比冒泡排序略好,但仍然不如插入排序。

希尔排序

希尔排序是一种高效的排序算法,它是直接插入排序的改进版本。它的基本思想是将待排序的元素按照一定的间隔分组,对每组中的元素进行插入排序,然后逐步缩小间隔,直到间隔为1,最后再对整个序列进行一次插入排序。希尔排序的关键在于间隔序列的选择。

func shellSort(arr []int) {
    n := len(arr)
    // 初始间隔设为数组长度的一半,然后每次将间隔除以2,直到间隔为1
    for gap := n / 2; gap > 0; gap /= 2 {
        // 对每个分组进行插入排序
        for i := gap; i < n; i++ {
            j := i
            for j-gap >= 0 && arr[j] < arr[j-gap] {
                arr[j], arr[j-gap] = arr[j-gap], arr[j]
                j -= gap
            }
        }
    }
}

在这个实现中,我们首先获取数组的长度,然后使用一个for循环来遍历间隔序列。外层循环从初始间隔开始,每次将间隔除以2,直到间隔为1。内层循环从每个分组的第二个元素开始遍历到最后一个元素。对于每个元素,我们将它与同组的前一个元素比较,如果它比前一个元素小,就将它们交换位置。交换完成后,我们继续向前遍历同组的前一个元素,直到找到第一个比当前元素小的元素或者到达分组的开头为止。当内层循环结束时,整个数组的所有分组都已经排好序了。

希尔排序的时间复杂度不是很容易计算,最坏情况下为O(n^2),但是在大多数情况下,它的时间复杂度要优于插入排序和选择排序。希尔排序也是一种不稳定的排序算法。