数据结构与算法 - 快速排序
快速排序
快速排序的核心思想也是分治法,分而治之。它的实现方式是每次从序列中选出一个基准值,其他数依次和基准值做比较,比基准值大的放右边,比基准值小的放左边,然后再对左边和右边的两组数分别选出一个基准值,进行同样的比较移动,重复步骤,直到最后都变成单个元素,整个数组就成了有序的序列。
我们以[ 8,2,5,0,7,4,6,1 ]
这组数字来进行演示
首先,我们随机选择一个基准值:
与其他元素依次比较,大的放右边,小的放左边:
然后我们以同样的方式排左边的数据:
继续排 0 和 1 :
由于只剩下一个数,所以就不用排了,现在的数组序列是下图这个样子:
单边扫描
快速排序的关键之处在于切分,切分的同时要进行比较和移动,这里介绍一种叫做单边扫描的做法。
我们随意抽取一个数作为基准值,同时设定一个标记 mark 代表左边序列最右侧的下标位置,当然初始为 0 ,接下来遍历数组,如果元素大于基准值,无操作,继续遍历,如果元素小于基准值,则把 mark + 1 ,再将 mark 所在位置的元素和遍历到的元素交换位置,mark 这个位置存储的是比基准值小的数据,当遍历结束后,将基准值与 mark 所在元素交换位置即可。
代码实现
void sort(vector<int> &arr)
{
sort(arr, 0, arr.size()-1)
}
void sort(vector<int> &arr, int start, int end)
{
if(end <= start) return;
//切分
int pivotIndex = partition(arr, start, end);
sort(arr, start, pivotIndex-1);
sort(arr, pivotIndex+1, end);
}
int partition(vector<int>& arr, int start, int end)
{
int pivot = arr[start];
int mark = start;
for(int i = start+1; i <= end; i++) {
if(arr[i] < pivot) {
//小于基准值 则mark+1,并交换位置。
mark++;
int p = arr[mark];
arr[mark] = arr[i];
arr[i] = p;
}
}
//基准值与mark对应元素调换位置
arr[start] = arr[mark];
arr[mark] = pivot;
return mark;
}
双边扫描
另外还有一种双边扫描的做法,看起来比较直观:我们随意抽取一个数作为基准值,然后从数组左右两边进行扫描,先从左往右找到一个大于基准值的元素,将下标指针记录下来,然后转到从右往左扫描,找到一个小于基准值的元素,交换这两个元素的位置,重复步骤,直到左右两个指针相遇,再将基准值与左侧最右边的元素交换。
我们来看一下实现代码,不同之处只有 partition 方法:
int partition(vector<int>& arr, int start, int end)
{
int left = start;
int right = end;
int pivot = arr[start]; // 第一个元素作为基准值
while(true) {
//从左往右扫描
while(arr[left] <= pivot) {
left++;
if(left == right) break;
}
//从右往左扫描
while(pivot < arr[right]) {
right--;
if(left == right) break;
}
// 左右指针相遇
if(left >= right) {
break;
}
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
int temp = arr[start];
arr[start] = arr[right];
arr[right] = temp;
return right;
}
极端情况
快速排序的时间复杂度和归并排序一样,[ 9,8,7,6,5,4,3,2,1 ]
,选取基准值 9 ,那么需要切分 n - 1 次才能完成整个快速排序的过程,这种情况下,时间复杂度就退化成了
所以说,快速排序的时间复杂度是
另外,快速排序的空间复杂度为
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南