快速排序算法
题目链接:https://www.acwing.com/problem/content/description/787/
吐槽:看了好几种快速排序的代码,要么是pivot为左边界AC不通过,要么就是边界情况没考虑清楚。属实恶心
下面写了3种AC通过的代码。(建议直接背下第二种或第三种)
先介绍下基本知识
快速排序的基本思想是基于分治
策略的,其算法思想如下。
- 分解:先从数列中取出一个元素作为基准元素(左、中、右、随机)。以基准元素为标准,将问题分解为两个子序列,使小于或等于基准元素的子序列在左侧,使大于基准元素的子序列在右侧。
- 治理:对两个子序列进行快速排序
- 合并:将排好序的两个子序列合并在一起,得到原问题的解。
第一种方法:
算法步骤:
- 首先选取数组的第一个元素作为基准元素pivot = q[l], i = l, j = r
- 先从右往左扫描,找小于pivot的数,如果找到,则q[i]和q[j]交换,且i++
- 从左向右扫描,找大于pivot的数,如果找到,则q[i]和q[j]交换,且j--
- 重复步骤2~3,直到i和j重合,所指的位置正好是pivot元素
- 至此一趟排序完成。此时以pivot为界,将数据分为两个子序列,左侧子序列元素都比pivot小,右侧子序列元素都比pivot大,然后再分别对这两个子序列进行快速排序。
注意:详细细节写在代码中
C++代码
void quick_sort(int q[], int l, int r){
if (l >= r) return; //递归出口:当区间没有元素 或 只有一个元素时 结束
int x = l + r >> 1, i = l, j = r; //直接选取左边界会超时,那么就选取中间元素,然后和左边界元素交换
swap(q[l], q[x]); //中间元素 和 左边界交换
int pivot = q[l]; //相当于pivot选取的是中间元素 步骤1完成
while(i < j){
while(i < j && q[j] > pivot) j--; // 写<=会超时 同下 并且一定先从j开始
if(i < j) swap(q[i++], q[j]); //步骤2完成
while(i < j && q[i] < pivot) i++;
if(i < j) swap(q[i], q[j--]); //步骤3完成
}
// i == j时退出循环 此时i和j所指的元素正好是pivot 递归处理左右
quick_sort(q, l, i - 1);
quick_sort(q, i + 1, r);
}
第二种方法:y总总结的模板
代码是用do-while实现了,感觉不太好了解
C++代码
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
第三种方法:类似y总总结的模板
代码是用while实现了,应该理解好多
void quick_sort(int q[], int l, int r){
if(l >= r) return;
int i = l, j = r, x = q[l + r >> 1];
while(i <= j){ // <=的目的:将i=j的情况继续处理,直至i>j,下面的i<=j同理
while(q[i] < x) i++; // <的目的:若用<=,则会在数据为大量重复数字时发生数组下标越界
while(q[j] > x) j--; // 此时 i 和 j 都指向不符合条件的元素
if(i <= j) swap(q[i++], q[j--]); //将 i 和 j 交换 然后 两个指针分别移动一位
}
//此时 j < i,即j在i的左边一位
quick_sort(q, l, j);
quick_sort(q, i, r);
}
本文作者:Ac_c0mpany丶
本文链接:https://www.cnblogs.com/keyongkang/p/15134907.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了