关于排序算法的模板集合
//升序排列
一.冒泡排序
冒泡排序(BubbleSort)指如果左边大于右边,则swap,否则停止
时间复杂度:最优On,最差On*n
最优解为不进行处理,最差情况为逆序
void BubbleSort(int *a,int n){
int end=n;
while(end>=1){
bool flag=false;
for(int i=1;i<n;i++){
if(a[i]>a[i+1]){
swap(a[i],a[i+1]);
flag=true;
}
}
if(!flag) break;
end--;
}//On*n~On
}
二.插入排序
选取未排序数,从已排序数列中从后往前扫描,如果已排序数列数大于该未排序数,将该已排序数向后移一位
时间复杂度 On~On*n
void InsertSort(int *a,int n){
for(int i=1;i<n;i++){
int tmp=a[i+1];
int end=i;
while(end>=1){
if(tmp<a[end]){
a[end+1]=a[end];
end--;
}else{
break;
}
}
a[end+1]=tmp;
}
}
三.桶排序
桶排序(BucketSort)是一种牺牲空间的排序方法,思路最为简单,缺点最为明显
缺点:浪费many空间,要求已知需排序数据的大致范围
时间复杂度 :On
空间复杂度:so long
void BucketSort(int *a,int *b,int n){
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++){
b[a[i]]++;
}
for(int i=0;i<=MAX+5;i++){
while(b[i]>0){
cout<<i<<" ";
b[i]--;
}
}
}
四.希尔排序
对数列先进行预排序,再对预排序的数列进行插入排序
简化了搜索的时间复杂度
void ShellSort(int *a,int n){
int gap=n;
while(gap>1){
gap=gap/2;
for(int i=1;i<=n-gap;i++){
int end=i;
int tmp=a[end+gap];
while(end>0){
if(tmp<a[end]){
a[end+gap]=a[end];
end-=gap;
}else{
break;
}
}
a[end+gap]=tmp;
}
}
}
五.选择排序
选择未排序数列中最小的一项的与未排序的首项进行swap
时间复杂度:On*n
void SelectSort(int *a,int n){
int begin=1;
while(begin<n){
int minn=begin;
for(int i=begin;i<=n;i++){
if(a[begin]>a[i]){
minn=i;
}
}
swap(a[begin],a[minn]);
begin++;
}
}
六.拓扑排序
严格来说,拓扑排序与以上的各种排序方式并不相同,
拓扑所处理的是对有向无环图的排序
详细思路并不在这里讨论,只附所写的代码
使用情景:有向无环图(DAG)
使用了队列&向量(数据结构)//大三will学习
#include<bits/stdc++.h>
#define MOL 80112002
using namespace std;
const int M=5e3+5;
vector<int> q[M];//用来存储每个点连接的边
queue<int> p;//拓扑排序所需的队列
int in[M],to[M];//用来储存每个点的入度和出度
void add(int x,int y){//添加x->y的边
to[x]++;//x的出度加一
in[y]++;//y的入度加一
q[x].push_back(y);//把y压入q[x]的vector中,存边
}
int n;//边数
int m;//点数
int main (){
ios::sync_with_stdio(false);
cin>>m>>n;
for(int i=1;i<=n;i++){
int a,b;
cin>>a>>b;
add(a,b);
}
for(int i=1;i<=m;i++){//先把入度为0的点压入队列
if(in[i]==0) p.push(i);
}
while(!p.empty()){//当队列为空时退出
int tot=p.front();//取出一个点
p.pop();
cout<<tot<<' ';
int a=sizeof(q[tot]);//a表示tot指向的点的个数
for(int i=0;i<to[tot];i++){//遍历
int nxt=q[tot][i];
in[nxt]--;//入度减一
if(in[nxt]==0) p.push(nxt);//如果该点的入度为0,压入队列
}
}
return 0;
}