当前位置: 首页 > news >正文

C++算法·排序

排序的定义

这个不用说吧
就是根据某个条件对一个数列进行有序的操作
例如要求从小到大排序、从大到小排序等等

排序的分类

比较排序(Comparison(Comparison(Comparison Sorts)Sorts)Sorts)

特点:通过元素间的比较决定顺序
时间复杂度下限O(nO(nO(n logloglog n)n)n)

排序算法平均时间复杂度空间复杂度稳定性特点
冒泡排序O(n2)O(n²)O(n2)O(1)O(1)O(1)稳定简单但慢
选择排序O(n2)O(n²)O(n2)O(1)O(1)O(1)不稳定每次选最小放前面
插入排序O(n2)O(n²)O(n2)O(1)O(1)O(1)稳定对小规模数据高效
快速排序O(nO(nO(n logloglog n)n)n)O(logn)O(log n)O(logn)不稳定分治思想,实际最快
归并排序O(nO(nO(n logloglog n)n)n)O(n)O(n)O(n)稳定分治+合并,需额外空间
堆排序O(nO(nO(n logloglog n)n)n)O(1)O(1)O(1)不稳定利用堆结构

非比较排序(Non−Comparison(Non-Comparison(NonComparison Sorts)Sorts)Sorts)

特点:不直接比较元素,利用数值特性
时间复杂度:可突破O(nO(nO(n logloglog n)n)n)下限

排序算法时间复杂度空间复杂度稳定性适用场景
计数排序O(n+k)O(n+k)O(n+k)O(k)O(k)O(k)稳定整数且范围小(kkk为范围)
桶排序O(n+k)O(n+k)O(n+k)O(n+k)O(n+k)O(n+k)稳定数据均匀分布
基数排序O(d(n+k))O(d(n+k))O(d(n+k))O(n+k)O(n+k)O(n+k)稳定整数按位排序(ddd为位数)

建议

  • 通用快速排序(STL 的 sort
  • 稳定归并排序(STL 的 stable_sort
  • 小范围整数计数排序
  • 数据大堆排序(避免快排递归栈溢出)

:实际代码实现需根据数据特点选择

模板代码示例

这里给出常用的冒泡排序、选择排序、快速排序等
内容解释在代码注释里,全是干货可以直接食用

冒泡排序

#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];//核心代码for(int i=1;i<=n-1;i++){//n-1轮排序bool swapped=false;//优化:记录是否发生交换for(int j=1;j<=n-i;j++){//每轮比较前n-i个元素if(a[j]>a[j+1]){//相邻元素比较swap(a[j],a[j+1]);//交换swapped=true;}}if(!swapped)break;//本轮无交换说明已有序}for(int i=1;i<=n;i++)cout<<a[i]<<" ";//排序后结果return 0;
}

选择排序

#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];//核心代码for(int i=1;i<=n-1;i++){//n-1轮选择int minn=i;//记录最小值位置for(int j=i+1;j<=n;j++){//在未排序部分找最小值if(a[j]<a[minn])minn=j;}swap(a[i],a[minn]);//把最小值放到已排序末尾}for(int i=1;i<=n;i++)cout<<a[i]<<" ";//排序后结果return 0;
}

快速排序

可以用自己写函数更改排序条件
一般配合结构体使用,下篇文章有讲到

#include<iostream>
#include<algorithm>
//sort函数必要头文件,如果不想加可以自己写sort
using namespace std;
int a[5000001];//待排序数组
int main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];sort(a+1,a+n+1);//直接调用sort函数排序[1,n]区间for(int i=1;i<=n;i++)cout<<a[i]<<" ";//排序后结果,快排是最简单的排序~return 0;
}

插入排序

#include<iostream>
using namespace std;
int a[5000001];//待排序数组
int main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];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;//插入元素}for(int i=1;i<=n;i++)cout<<a[i]<<" ";//排序后结果return 0;
}

计数排序

#include<iostream>
using namespace std;
const int N=5000001;
const int K=100000;//数据范围自行调整
int a[N],cnt[K],b[N];
void csort(int n){for(int i=1;i<=n;i++)cnt[a[i]]++;for(int i=1;i<K;i++)cnt[i]+=cnt[i-1];for(int i=n;i>=1;i--)b[cnt[a[i]]--]=a[i];for(int i=1;i<=n;i++)a[i]=b[i];
}
int main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];csort(n);for(int i=1;i<=n;i++)cout<<a[i]<<" ";return 0;
}

这个注释不好写,讲一下

变量定义说明:

  • a[]:待排序数组
  • cnt[]:计数数组
  • b[]:临时存储排序结果
  • K:数据最大值范围

流程:

  • 统计每个元素出现次数(cnt[a[i]]++
  • 计算前缀和确定元素位置(cnt[i]+=cnt[i-1]
  • 反向填充保证稳定性(b[cnt[a[i]]--]=a[i]
  • 回写到原数组(a[i]=b[i]

注意事项:

  • 仅适用于非负整数排序
  • 数据范围K需要提前确定
  • 时间复杂度:O(n+K)(线性时间)

例题实战

【题目传送门】【题目传送门】【题目传送门】

P1177 【模板】排序

题目描述

将读入的 NNN 个数从小到大排序后输出。

输入格式

第一行为一个正整数 NNN

第二行包含 NNN 个空格隔开的正整数 aia_iai,为你需要进行排序的数。

输出格式

将给定的 NNN 个数从小到大输出,数之间空格隔开,行末换行且无空格。

输入输出样例 #1

输入 #1

5
4 2 4 5 1

输出 #1

1 2 4 4 5

说明/提示

对于 20%20\%20% 的数据,有 1≤N≤1031 \leq N \leq 10^31N103

对于 100%100\%100% 的数据,有 1≤N≤1051 \leq N \leq 10^51N1051≤ai≤1091 \le a_i \le 10^91ai109

分析

简单的排序模板题,范围不大
可以直接用最简单的sortsortsort秒过
没看懂的可以看上方代码↑有注释解释
直接上代码↓

例题代码

#include <iostream>
#include <algorithm>
using namespace std;
int n,a[1000005];//数组范围10^5
int main(){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];sort(a+1,a+1+n);//快排for(int i=1;i<=n;i++)cout<<a[i]<<" ";return 0;
}

题单推荐

排序⋅题单排序·题单排序题单
例题和题单来自洛谷洛谷洛谷

~ 完结撒花完结撒花完结撒花 ~

附:这篇比较简单,之前忘记讲了
之前漏了很多,把基础补回来之后再讲后面的例题
下一篇预告:递推递归或者结构体

http://www.dtcms.com/a/328083.html

相关文章:

  • 第六十四章:AI的“觅食”之路:数据采集器设计与多源数据获取
  • DL-FWI 的三项主要任务: 网络构建, 数据生成, 训练控制
  • 跑腿APP开发未来趋势:同城O2O系统源码在智能调度与个性化中的进化
  • Spring Boot项目中调用第三方接口
  • HCIP项目之OSPF综合实验
  • Flux.1系列模型解析--Kontext
  • 8月12号打卡
  • 【Leetcode hot 100】560.和为K的子数组
  • 无人机航拍数据集|第13期 无人机城市斑马线目标检测YOLO数据集963张yolov11/yolov8/yolov5可训练
  • 为什么304不锈钢仍会生锈?
  • Ubuntu20.06环境下安装VS Code及中文设置方法
  • CSRF 攻击
  • 【机器学习】什么是DNN / MLP(全连接深度神经网络, Deep Neural Network / Multilayer Perceptron)?
  • 【Python】支持向量机SVM
  • Web攻防-业务逻辑篇Fuzz技术数据并发条件竞争JS挖掘参数盲猜Turbo插件SRC
  • c#联合Halcon进行OCR字符识别(含halcon-25.05 百度网盘)
  • 下一代防火墙部署
  • TF-IDF 红楼梦关键词提取
  • 全文深度剖析国产化数据库达梦之备份恢复体系
  • nurbs曲线的matlab
  • RabbitMQ面试精讲 Day 20:RabbitMQ压测与性能评估
  • Hystrix核心内容
  • JUC 面试知识点大纲
  • Notepad++插件开发实战
  • 【从0带做】基于Springboot3+Vue3的校园表白墙系统
  • Java进阶学习之不可变集合
  • 【实时Linux实战系列】基于RFID的实时资产追踪系统
  • 矩形前缀和
  • 【GESP】C++一级知识点之【集成开发环境】
  • 【DL】深层神经网络