[排序算法] 计数排序 (C++)
计数排序解释
计数排序思想
计数排序 的思想十分简单,就是统计每个数字出现的次数。它是一种非基于比较的排序算法,其是通过额外的空间换取时间的方式,来实现更加高效的排序。😇😇😇
计数排序步骤
1、假设我们有一个长度为 n 的待排序序列,其所有元素组成的集合为 S,集合的数据范围为 0 - k。
我们只需要定义一个大小为 k 的数组 count[] 用来统计每个数字出现的次数;
2、之后按照统计数组 count[] 下标顺序将数字放入原数组中即可完成排序。
计数排序动态演示
统计每个数字个数
放回原数组
计数排序时间复杂度及其局限性
时间复杂度分析
计数排序时间复杂度为 O(n + k),其中 n 为数据元素个数, k 为数据元素范围大小。
当数据范围大小 k 恰好和 n 相等时,时间复杂度为 O(n)。
局限性分析
计数排序有几大局限性
1、当我们的数据范围非常大时,我们需要开辟很多的空间。夸张地讲,假如有1000万个数据,数据范围非常大,这个时候用计数排序是十分低效的;
2、当我们的数据之间跨度比较大,比如说出现了数字 1,但是下一个出现的数字是10000,2-9999中间的数字都没有出现,那么也浪费了很多的空间;
3、当我们的数据范围无法确定时,我们不知道要开辟多少大小的 count[] 数组;
4、计数排序还有一大局限性是,他不可以对小数进行排序,毕竟统计数组的下标都是整数呢。😏
计数排序核心代码
//计数排序实现方法如其名 但是局限性很大。
//(若最大数很大或者数值范围无法确定时,消耗时间反而很会多,并且空间复杂度也高)
void CountingSort(vector<int> &a){
vector<int> count(MAX, 0); //统计每个数字出现的次数
for(auto &x : a)
count[x]++;
int k = 0;
for(int num = 0; num < MAX; num++){
while(count[num]){
a[k++] = num;
count[num]--;
}
}
vector<int>().swap(count); //相当于用一个空直接换掉
}
完整程序源代码
#include<iostream>
#include<vector>
#include<ctime>
using namespace std;
const int MAX = 101;
//计数排序实现方法如其名 但是局限性很大。
//(若最大数很大或者数值范围无法确定时,消耗时间反而很会多,并且空间复杂度也高)
void CountingSort(vector<int> &a){
vector<int> count(MAX, 0); //统计每个数字出现的次数
for(auto &x : a)
count[x]++;
int k = 0;
for(int num = 0; num < MAX; num++){
while(count[num]){
a[k++] = num;
count[num]--;
}
}
vector<int>().swap(count); //相当于用一个空直接换掉
}
void show(vector<int> &v){
for(auto &x : v)
cout<<x<<" ";
cout<<endl;
}
main(){
vector<int> a;
int n = 100;
srand((int)time(0));
while(n--)
a.push_back(rand() % 100 + 1);
show(a);
CountingSort(a);
cout<<endl<<endl;
show(a);
}
程序运行结果图
一切都是命运石之门的选择,本文章来源于博客园,作者:MarisaMagic,出处:https://www.cnblogs.com/MarisaMagic/p/16910146.html,未经允许严禁转载