c++ 快速排序(看这一篇就够了)
·
1.定义
快速排序是一种分治法(Divide and Conquer)的排序算法。它通过选取一个“基准”元素,将待排序的数组分成两部分,使得一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素,然后递归地对这两部分分别进行排序,最终实现整个数组的有序排列
不懂分治法的,先去看分治算法c++详解(看这一篇就够了)_分治算法 c++-CSDN博客
2.概述
快速排序由 C. A. R. Hoare 在 1960 年提出,是一种基于**分治法(Divide and Conquer)**的高效排序算法。它通过递归地将数组划分成较小的子数组进行排序,平均时间复杂度为 O(n log n),在大多数情况下比其他 O(n log n) 级别的排序算法(如归并排序)更快。
快速排序的特点:
- 时间复杂度:
- 平均情况:O(n log n)
- 最坏情况(基准总是最小或最大值):O(n²)
- 空间复杂度:O(log n)(递归调用栈的开销)
- 稳定性:不稳定(可能交换相同元素的位置)
- 适用性:适用于大规模数据排序,尤其是内排序(in-place sorting)。
快速排序因其高效性而成为最常用的排序算法之一,并且是许多标准库排序函数的核心实现(如 std::sort 在许多实现中都基于快速排序和堆排序的组合)。
3.原理
算法步骤
- 选择基准(Pivot):可以是第一个、最后一个、中间的某个元素,或随机选择。
- 划分(Partition):调整数组,使左侧元素 ≤ 基准,右侧元素 ≥ 基准,并将基准放入正确位置。
- 递归(Recursion):对左右子数组分别递归执行快速排序,直到子数组长度为 1 或 0,排序完成。
举个栗子
假设有一个无序数组:
[9, 7, 5, 11, 12, 2, 14, 3, 10, 6]
1. 选择基准(Pivot)
- 从数组中选一个元素作为基准值(Pivot)。
- 这里我们选择最后一个元素
6作为基准值(实际可以选第一个、随机选择或取中位数)。
2. 划分(Partition)
- 重新排列数组,使得所有小于等于基准值的元素放到左边,大于基准值的元素放到右边。
- 遍历数组,把比
6小的数放到左侧,比6大的数放到右侧,最终形成:[5, 2, 3, 6, 12, 14, 11, 9, 10, 7]5, 2, 3在左边(小于6)。12, 14, 11, 9, 10, 7在右边(大于6)。6被放到了正确的位置。
3. 递归排序左右子数组
- 左子数组
[5, 2, 3]递归执行快速排序:- 选择
3作为基准值 → 排列为[2, 3, 5] - 左边
[2]和右边[5]已经有序,无需递归。
- 选择
- 右子数组
[12, 14, 11, 9, 10, 7]递归执行快速排序:- 选择
7作为基准值 → 排列为[7, 9, 10, 11, 12, 14] - 左边
[7]已有序,无需递归。 - 右边
[9, 10, 11, 12, 14]继续递归,最终变成[7, 9, 10, 11, 12, 14]。
- 选择
4. 组合最终结果
排序完成后,最终数组变成:
[2, 3, 5, 6, 7, 9, 10, 11, 12, 14]
4.代码
#include<bits/stdc++.h>
using namespace std;
int arr[110],n;
void quickSort(int left,int right)
{
if(left>=right)
{
return;
}
int pivot=arr[right],i=left-1;
for(int j=left;j<right;j++)
{
if(arr[j]<=pivot)
{
swap(arr[++i],arr[j]);
}
}
swap(arr[i+1],arr[right]);
quickSort(left,i);
quickSort(i+2,right);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
quickSort(1,n);
for(int i=1;i<=n;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
return 0;
}
代码解释:
- 选择
arr[right]作为基准元素。 - 使用两个指针:
i指向小于等于基准元素的部分的最后一个元素,j遍历整个数组。 - 如果
arr[j] <= pivot,则交换arr[i]和arr[j],并且i增加。 - 最后将基准元素放到其正确的位置,并递归排序左侧和右侧的子数组。
5.提醒
- 快速排序的性能受基准选择的影响。如果每次选择的基准是最小或最大值(比如选择第一个或最后一个元素),在某些情况下(例如已排序或逆序数组),其时间复杂度可能会退化到 O(n²)。
- 为了避免最坏情况,可以采用随机化快速排序或三数取中法来选择基准元素。
- 快速排序是不稳定的排序算法,因此如果需要稳定排序,可以考虑使用归并排序或插入排序。
更多推荐


所有评论(0)