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

87 阅读3分钟

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

快速排序

快速排序是一种基于比较的排序算法,它的基本思想是通过一次排序将待排序的元素分为两个部分,一部分小于某个值(称为pivot),一部分大于等于pivot。然后对这两个部分分别进行递归排序,直到整个序列有序。

func quickSort(arr []int, left, right int) {
    if left >= right {
        return
    }
    // 选择pivot
    pivot := arr[left]
    i, j := left, right
    for i < j {
        // 从右边开始找第一个小于pivot的元素
        for i < j && arr[j] >= pivot {
            j--
        }
        // 从左边开始找第一个大于pivot的元素
        for i < j && arr[i] < pivot {
            i++
        }
        // 交换arr[i]和arr[j]的位置
        arr[i], arr[j] = arr[j], arr[i]
    }
    // 将pivot放在正确的位置上
    arr[left], arr[i] = arr[i], arr[left]
    // 对左右两个部分分别进行递归排序
    quickSort(arr, left, i-1)
    quickSort(arr, i+1, right)
}

在这个实现中,我们首先定义一个快速排序函数,它接受一个数组和两个整数left和right,表示排序的区间范围。如果left>=right,说明数组已经有序,可以直接返回。否则,我们选择数组的第一个元素作为pivot,然后使用两个指针i和j来分别指向数组的左右两端。然后,我们让j从右端开始向左移动,直到找到第一个小于pivot的元素;让i从左端开始向右移动,直到找到第一个大于等于pivot的元素。然后交换arr[i]和arr[j]的位置,继续移动i和j,直到i>=j为止。最后,我们将pivot放在正确的位置上,这里使用了交换arr[left]和arr[i]的位置来实现。然后,我们分别对左右两个部分进行递归排序。

快速排序的时间复杂度为O(nlogn),其中n是待排序的元素个数。快速排序是一种不稳定的排序算法。它通常比其他基于比较的排序算法更快,但是它的性能高度依赖于选择的pivot,如果pivot的选择不当,可能会导致算法的性能降低。

归并排序

归并排序是一种基于分治思想的排序算法,它将待排序的序列分为两个子序列,分别进行递归排序,最后将两个有序子序列合并成一个有序序列。归并排序的基本思想可以概括为“分而治之,然后合并”。

func mergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }
    // 将数组分为两个部分
    mid := len(arr) / 2
    left := mergeSort(arr[:mid])
    right := mergeSort(arr[mid:])
    // 合并两个有序子序列
    return merge(left, right)
}

func merge(left, right []int) []int {
    result := make([]int, 0, len(left)+len(right))
    i, j := 0, 0
    for i < len(left) && j < len(right) {
        if left[i] <= right[j] {
            result = append(result, left[i])
            i++
        } else {
            result = append(result, right[j])
            j++
        }
    }
    result = append(result, left[i:]...)
    result = append(result, right[j:]...)
    return result
}

在这个实现中,我们首先定义一个归并排序函数,它接受一个数组作为参数。如果数组的长度小于等于1,说明数组已经有序,可以直接返回。否则,我们将数组分为两个部分,分别对左右两个部分进行递归排序。然后,我们调用merge函数将两个有序子序列合并成一个有序序列。merge函数接受两个有序子序列作为参数,返回一个合并后的有序序列。在merge函数中,我们定义一个result数组来保存合并后的有序序列。我们使用两个指针i和j来分别指向左右两个有序子序列的开头,比较left[i]和right[j]的大小,将较小的元素放入result数组中。然后,我们继续移动i和j,直到i或j超出数组范围为止。最后,我们将剩余的元素依次放入result数组中,返回result数组。

归并排序的时间复杂度为O(nlogn),其中n是待排序的元素个数。归并排序是一种稳定的排序算法,它的性能不受输入数据的影响。