【排序算法之快速排序】

概要:本期我们学习排序算法中的快速排序,会着重讲解算法的核心思想、时空复杂度分析以及代码的实现。

一、快速排序

快速排序(Quicksort)是一种常见的排序算法。

二、核心思想

快速排序的核心思想是分治法,即将问题分解成小的子问题来解决。具体来说:

  1. 快速排序的基本思想是选取一个枢轴(pivot),作为基准元素。
  2. 然后将数组分为两部分,使得左边的元素都小于等于枢轴,右边的元素都大于等于枢轴。
  3. 接着对左右两部分分别递归地进行快速排序,直到排序完成。
    跳转到这个网页,直观地感受归并排序吧:)

三、时空复杂度分析

快速排序的时间复杂度分析可以从最好、最坏和平均三个层面进行分析。

  1. 最好情况是当每次选取的枢轴都刚好是当前子序列的中位数时,此时每次划分都能够把序列均分为两个长度相等的子序列。在这种情况下,快速排序的时间复杂度为O(nlogn)

  2. 最坏情况是当每次选取的枢轴都是当前子序列的最小或最大值,此时每次划分都只能将序列划分成一个子序列和一个空序列,这种情况下快速排序的时间复杂度为O(n^2)

  3. 在平均情况下,快速排序的时间复杂度为O(nlogn)。快速排序的平均时间复杂度的分析比较复杂,需要用到数学期望的知识。假设每次选取的枢轴都能将当前序列分为长度相等的两个子序列,那么快速排序的时间复杂度就是O(nlogn)。在实际情况下,每次选取的枢轴并不能完美地将序列均分,但是经过证明,平均情况下每次划分会将序列分为比例为3:7左右的两个子序列,因此时间复杂度为O(nlogn)。

在快速排序的过程中,我们使用了递归的方式对序列进行划分和排序,每次递归都会占用一定的栈空间。

  1. 在最坏情况下,快速排序的递归深度为n,此时需要O(n)的栈空间。
  2. 在平均情况下,快速排序的递归深度为logn,因此需要O(logn)的栈空间。

因此,快速排序的空间复杂度是O(logn)。需要注意的是,由于快速排序是一种原地排序算法,不需要额外的辅助空间进行排序,因此除了栈空间外,快速排序并不需要额外的空间。
然后,由于快速排序过程中需要通过递归方式来进行序列划分,其中会导致元素相对顺序改变,因此,快速排序不是一种稳定排序算法。

四、代码实现

下面展示C++的实现源码:

void SortFuncation::TraverQuickSort(QVector<int> &arr,int left,int right)
{
    
    
    // 定义左右指针、中轴值和临时变量
    int i = left, j = right;
    int pivot = arr[(left + right) / 2];
    int tmp;
    // 分区操作
    while (i <= j)
    {
    
    
        while (arr[i] < pivot)
           i++;
        while (arr[j] > pivot)
           j--;
        if (i <= j) {
    
    
           // 交换 arr[i] 和 arr[j] 的值
           tmp = arr[i];
           arr[i] = arr[j];
           arr[j] = tmp;
           i++;
           j--;
        }
   }
    // 递归调用
    if (left < j)
        TraverQuickSort(arr, left, j);
    if (i < right)
        TraverQuickSort(arr, i, right);
}

结尾

对于平均时间复杂度为O(n log n)级别的排序算法的学习到这就结束了,我们来简单做一些总结:

算法名称 是否为原地排序 是否为稳定排序 最好的时间复杂度 最坏的时间复杂度 平均的时间复杂度
归并排序 O(n log n) O(n log n) O(n log n)
快速排序 O(n log n) O(n^2) O(n log n)

下期我们开始学习一些外部排序算法:)

猜你喜欢

转载自blog.csdn.net/wddkxg/article/details/129769653