排序算法梳理

选择排序

为什么叫选择,因为每次都选出来两个大冤种进行交换
这样复杂度就成为了优秀的 O ( n 2 ) O(n^2) O(n2)

void selection_sort(int a[],int n){
	for(int i=1;i<n;++i){
		int tmp=i;
		for(int j=i+1;j<=n;++j){
			if(a[j]<a[tmp]) tmp=j;
		} 
		swap(a[tmp],a[i]);
	} 
}

非常之easy,因为涉及swap这个操作,这个排序不稳定

冒泡排序

这个就有点东西了昂(只是指名字):在这个算法执行的过程中,较小的元素会像是气泡慢慢地浮出水面
它每一轮比较相当于把最大的元素往后面送,所以我们只要需要执行 ( n − 1 ) + ( n − 2 ) + . . . + 1 = ( n − 1 ) n 2 (n-1)+(n-2)+...+1=\frac{(n-1)n}{2} (n1)+(n2)+...+1=2(n1)n
所以复杂度就是 O ( n 2 ) O(n^2) O(n2) 而且它是稳定的

void Bubble_sort(int a[], int n) {
	for (int i = 1; i < n; i ++) {
		int cnt = 0;
		for (int j = 1; j <= n-i; j++) {
			if (a[j] > a[j+1]) { 
				a[j]=a[j]^a[j+1],a[j+1]=a[j]^a[j+1],a[j]=a[j]^a[j+1];
				cnt=1;
			}
		}
		if (!cnt) break;
	}
}

冒泡是稳定的e

插入排序

这个排序但凡有点生活经历的人都会,因为你打扑克(假设只有你一个人摸牌)的时候就是从待排的扑克堆里拿出一张,然后在从你手里的牌中找个合适的位置插入,复杂度 O ( n 2 ) O(n^2) O(n2)
插入排序是稳定的昂

void insert_sort(int a[],int n){
	for(int i=1;i<n;++i){
		int tmp=a[i],j=i-1;
		while(j>=0&&a[j]>tmp){
			a[j+1]=a[j];
			j--;
		}
		a[j+1]=tmp;//上边的while循环你把a[j]挪到a[j+1],准备把手里的牌放到a[j]但是又j-- ,所以是这样写
	}
} //我这个写法非常的帅气昂  这a[i]就是你摸出来的牌   a[j]就是你手里牌的最后一张 因为i前面都排好序了(这就是插入排序的结果)
//然后每次比较 举个例子  259 你排三  最后成为这样  2559 然后再变成 2359 相当于把比你大的都往后移一格  

基数排序

这个排序算法的核心就在于每次按照个、十……的顺序排序(只能按照这个顺序,因为如果按照最高位排序的话后面会出问题的),它的时间复杂度取决于你所选择的k : : : O ( log ⁡ k m a x x ∗ ( n + k ) ) O(\log_{k}{maxx} *(n+k)) O(logkmaxx(n+k)) 前面的通常可以看成是常数不考虑**
基数排序是稳定的昂

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,k,val[N],cnt[N],tmp[N],m;
void init(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i) scanf("%d",&val[i]);
	int maxx=val[1];m=1;
	for(int i=2	;i<=n;++i) maxx=max(maxx,val[i]);
	while(maxx>=k){
		maxx/=k;
		m++;
	} 
}
void radix_sort	(){
	int base=1;
	for(int i=1;i<=m;i++){
		memset(cnt,0,sizeof cnt);
		for(int j=1;j<=n;++j) cnt[val[j]/base%k]++;
		for(int j=1;j<=k;++j) cnt[j]+=cnt[j-1];
		for(int j=n;j;j--){
			tmp[cnt[val[j]/base%k]]=val[j];
			cnt[val[j]/base%k]--;
		} 	
		for(int j=1;j<=n;++j) val[j]=tmp[j];	
		base*=k;
	}
}
int main(){
	init();
	solve();
	for(int i=1;i<=n;++i) printf("%d ",val[i]);
	return 0;
} 

桶排序

就是跟分块一样,按值域分成若干个桶,然后进行排序(桶内插排,因为范围小)
因为这份代码基于插排,所以是稳定的

const int N = 100010;
int n, w, a[N];//w为值域最大值
vector<int> bucket[N];
void insertion_sort(vector<int>& A) {
  for (int i = 1; i < A.size(); ++i) {
    int key = A[i],j = i - 1;
    while (j >= 0 && A[j] > key) {
      A[j + 1] = A[j];
      --j;
    }
    A[j + 1] = key;
  }
}

void bucket_sort() {
  int bucket_size = w / n + 1,p=0;
  for (int i = 0; i < n; ++i) bucket[i].clear();
  for (int i = 1; i <= n; ++i)  bucket[a[i] / bucket_size].push_back(a[i]);
  for (int i = 0; i < n; ++i) {
    insertion_sort(bucket[i]);
    for (int j = 0; j < bucket[i].size(); ++j) {
      a[++p] = bucket[i][j];
    }
  }
}

归并排序

#include <bits/stdc++.h>
using namespace std;
const int N=105;
int n,a[N],tmp[N];
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=1,i=l,j=mid+1;
	while(i<=mid&&j<=r)
		if(a[i]<=a[j]) tmp[k++]=a[i++];
		else tmp[k++]=a[j++];
	while(i<=mid) tmp[k++]=a[i++];
	while(j<=r) tmp[k++]=a[j++];
	for(int i=l,j=1;i<=r;++i,j++) a[i]=tmp[j];
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	merge_sort(a,1,n);
	for(int i=1;i<=n;++i) printf("%d ",a[i]);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值