关于排序算法的模板集合

关于排序算法的模板集合

//升序排列

一.冒泡排序

冒泡排序(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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值