排序算法整理C++(初赛)
排序算法整理
常见考点#
- 将一个乱掉的字符串排回有序(以交换为基本操作)的最少操作,就是冒泡排序。
- 排序算法的稳定性(考的多)
- 排序算法的时间复杂度(考的比较少)
排序算法的稳定性#
稳定性是指排序前两个元素a1 = a2,a1在前。排序过后,倘若a1始终在前,则算法是稳定的,否则是不稳定的。
稳定的#
不稳定的#
各个算法细锁#
冒泡排序#
基本思路:双重循环遍历数组,交换两个相邻的逆序的数字。时间复杂度一般 - ,最坏 - ,最好。
代码#
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n - i; j ++)
{
if(a[j] > a[j + 1])
swap(a[j], a[j + 1]);
}
}
都说最优复杂度是O(N),但显然这个程序怎么看都是,实际上是优化过的。考试的时候记住就行。
选择排序#
基本思路:遍历一遍数组 i in (1, n + 1),从 i 数开始遍历到后面,寻找最小的比它小的数,与它交换。
关于为什么选择排序是不稳定的?
举个例子:5 3 5 2 7
第一个5会与2交换
无论如何都是。
代码#
for(int i = 1; i < n; i ++)
{
int min = i;
for(j = i + 1; j <= n; j ++)
{
if(a[min] > a[j])
min = j;
swap(a[i], a[min]);
}
}
归并排序#
分治思想,将数组中所有的数递归分为两个一组,组内排序。回溯时再一步一步排序。
时间复杂度
网上讲的挺好的归并排序MergeSort(通俗易懂_kevinmeanscool的博客-CSDN
这个算法还能用来求逆序对,所以在复赛中也挺重要 虽然现在一般复赛不会考,只要在else后面(代码)加一句ans += mid - i +1
,但我不知道原理。
代码#
void merge_sort(int a[], int l, int r){
if(l >= r)
return;
int mid = l + r >> 1;
merge_sort(a, l, mid);
merge_sort(a, mid + 1, r);
int k = 0;
int i = l;
int j = mid + 1;
while(i <= mid && j <= r){
if(a[i] <= a[j])
f[k ++] = a[i ++];
else
f[k ++] = a[j ++];
}
while(i <= mid) f[k ++] = a[i ++];
while(j <= r) f[k ++] = a[j ++];
for(i = l, j = 0; i <= r; i ++, j ++){
a[i] = f[j];
}
}
插入排序#
基本思路:从第二个元素开始,和前面的元素比较,倘若前面的元素更大就往前移,直到遇到一个小于等于自己的元素。
最优: 平均: 最差:
代码#
for(int i = 2; i <= n; i ++)
{
int key = a[i];
int j = i - 1;
while(j >= 1 && a[j] > key)
{
a[j + 1] = a[j];
j --;
}
a[j + 1] = key;
}
希尔排序#
一种插入排序的优化版。
思路:先把所有数分组(很常见的排序算法思路),怎么分?比如数组一共8个数那就隔4隔为一组。a[0]a[4]一组,a[1]a[5]一组。之后组内排序。然后减少分组间隔为2。一次类推,直至间隔为1。
没听懂可以看看视频
为什么说希尔排序是优化版的插入排序,就是因为一次的组内排序都是插入排序实现的。
平均,最坏,最好。
代码就不放了,我也没敲过
堆排序#
想法就是维护一个大根堆,每一次取出根节点。
时间复杂度都是。
基数排序#
时间复杂度
快速排序#
基本思路:找一个基准数,先由i从左边出发,找到一个小于,j再从右边出发,找一个小于基准数的数。分开区间,重复此操作。时间复杂度平均,最优也是,最差。
代码#
void qsort(int l, int r)
{
int mid = a[l + r >> 1];
int i = l, j = r;
do{
while(a[i] < mid) i ++;
while(a[j] > mid) j --;
if(i <= j)
{
swap(a[i], a[j]);
i ++;
j --;
}
}while(i <= j);
if(l < j) qsort(l, j);
if(i < r) qsort(i, r);
}
int main()
{
qsort(1, n);
}
根据代码图解#
(如果加载不出来请刷新,因为图放在Github):
数组:[3, 2, 9, 5, 1, 8, 2]
找到了
交换,注意i ++, j -- 不然会死循环
i 不再动了,因为a[i] = mid
这里没写 i ++, j --
本文来自博客园,作者:huaziqi 转载请注明原文链接:https://www.cnblogs.com/huaziqi/p/16654520.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话