桶排序、基数排序、计数排序

参考链接:https://blog.csdn.net/qq_19446965/article/details/81517552

桶排序

  • 首先求出最大值最小值,把此区间划分为k个区间(即k个桶),再分别对桶内元素进行排序,将桶内元素合并得到排序结果。
  • 假设数据均匀分布,每个桶内元素为 n/k 个,并对桶内元素通过快排排序,每次排序复杂度为O(n/k log(n/k)),总的时间复杂度为O(n) + O(k)*O(n/k log(n/k))=O(n) + O(n log(n/k)),当k接近n时,复杂度可以认为是 O(n)
  • 桶排序的复杂度与建桶的效果紧密相连,常见的建桶思路为将最大值最小值之间的区间平分,或桶的个数为 2^n,10^n
  • 分治思想

基数排序

  • 非比较算法
  • 将所有待排整数统一为位数相同的整数(常见的为非负整数,对代码稍作修改,负整数也可通过基数排序进行排序)
  • 从最低位或最高位开始一次进行稳定排序,完成之后整个序列即为一个有序序列

计数排序

  • 以空间换时间
  • 遍历数组统计每个数出现的次数,根据统计结果写回数组
  • 是一种特殊的桶排序,当桶的个数最大时,桶排序即为计数排序

复杂度比较

//d为k进制下最长的位数

代码实现

代码实现思路与:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

基本一致

//sort
#include<iostream>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;

void bucketSort(vector<int> &arr){
	//将min和max等分成n份
	int low=999999999;
	int high=-999999999;
	for(int i=0;i<arr.size();i++){
		low=min(low,arr[i]);
		high=max(high,arr[i]);
	} 
	int size=(high-low)/10+1;  //一个桶的区间大小 
	vector<int> bucket[10];
	for(int i=0;i<arr.size();i++){
		int index=(arr[i]-low)/size;
		bucket[index].push_back(arr[i]); 
	}
	for(int i=0;i<10;i++){
		int bsize=bucket[i].size();
		sort(bucket[i].begin(),bucket[i].end());	
	}
	int index=0;
	for(int i=0;i<10;i++){
		for(int j=0;j<bucket[i].size();j++){
			arr[index]=bucket[i][j];
			index++;
		}
	}
}

//基数排序 
//从低位开始排序 
void redixSort(vector<int> &arr){
	int maxx=-999999999;
	for(int i=0;i<arr.size();i++){
		maxx=max(maxx,arr[i]);  //获取最大值 
	}
	int exp=10;
	while(maxx/exp!=0){
		exp*=10;  //获取最大值的位数 
	}
	vector<int> bucket[10]; 
	int exp2=10;
	while(exp2<=exp){
		for(int i=0;i<arr.size();i++){
			bucket[(arr[i]%exp2)/(exp2/10)].push_back(arr[i]); //放到对应的桶中 
		}
		int index=0;
		for(int i=0;i<10;i++){
			for(int j=0;j<bucket[i].size();j++){
				arr[index]=bucket[i][j];
				index++;
			}
			bucket[i].clear();    //因为桶是重复使用的,所以在一轮结束之后注意将桶清空 
		}
		exp2*=10;
	}
}

//考虑负数,从低位开始排序 
//将桶的大小扩展到20个即可 
void redixSortp(vector<int> &arr){
	int maxx=-999999999;
	for(int i=0;i<arr.size();i++){
		maxx=max(maxx,arr[i]);  //获取最大值 
	}
	int exp=10;
	while(maxx/exp!=0){
		exp*=10;  //获取最大值的位数 
	}
	vector<int> bucket[20];  
	int exp2=10;
	while(exp2<=exp){
		for(int i=0;i<arr.size();i++){
			bucket[(arr[i]%exp2)/(exp2/10)+10].push_back(arr[i]); //放到对应的桶中 
		}
		int index=0;
		for(int i=0;i<20;i++){
			for(int j=0;j<bucket[i].size();j++){
				arr[index]=bucket[i][j];
				index++;
			}
			bucket[i].clear();    //因为桶是重复使用的,所以在一轮结束之后注意将桶清空 
		}
		exp2*=10;
	}
}

void countSort(vector<int>& arr){
	int maxx=-999999999;
	int minn=999999999;
	for(int i=0;i<arr.size();i++){
		maxx=max(maxx,arr[i]);
		minn=min(minn,arr[i]);
	}
	int size=maxx-minn+1;
	int count[size]={0};
	for(int i=0;i<arr.size();i++){
		count[arr[i]-minn]++;
	}
	int index=0;
	for(int i=0;i<size;i++){
		for(int j=0;j<count[i];j++){
			arr[index]=i+minn;
			index++;
		}
	}
} 

int main(){
	int a[20]={45,95,23,78,21,2,5,0,-69,5,9,159,87,65,25,-56,56,56,57,100};
	vector<int> arr(a,a+20);
//	bucketSort(arr);
	redixSortp(arr);
//	countSort(arr);
	for(int i=0;i<20;i++){
		cout<<arr[i]<<" ";
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值