1. 前言
计数排序
是较简单的排序算法,其基本思想
是利用数组索引号有序的原理。
如对如下的原始数组
中的数据(元素)排序:
//原始数组
int nums[5]={9,1,7,6,8};
使用计数排序
的基本思路如下:
- 创建一个
排序数组
。数组的大小由原始数组的最大值决定,如原始数组的最大值为9
,则排序数组的长度为9+1
。为什么排序数组的长度需要如此设置,后文将做解释。
int sortNums[10]={0}; //初始化值为 0
-
读取原始数组中的
数据
,以此数据
作为排序数组
的索引号
,此数据出现的次数为排序数组的值。这也解释了为什么排序数组的长度必须是原始数组中最大值加
1
。因为排序数组
必须能为原始数组中的最大值
提供索引号。
- 然后输出
排序数组
中的值不为0
的索引号。
编码实现:
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
//原数组
int nums[5]= {9,1,7,6,8};
//排序数组
int sort[10]= {0};
//转存
for(int i=0; i<5; i++) {
sort[nums[i]]++;
}
//输出排序数组
for(int i=0; i<10; i++) {
if(sort[i]!=0)
cout<<i<<"\t";
}
return 0;
}
输出结果:
通过上文简述可知:
- 计数排序的时间复杂度为
O(n)
,时间复杂度还算可观。 - 但是空间复杂度也是
O(n)
。相比较如冒泡、选择……排序算法,计数排序算法是以空间换取时间。
2. 两个问题
2.1 排序数组的长度
计数排序利用数组索引号的有序而对数据排序,所以,需要把原无序数组中的数据
映射到排序数组的索引号上。于是,对排序数组的长度就会有一个最小值的约束,至少等于无序数组中的最大值加一。
如下面的无序数组:
int num[]={500,420,550};
为了保证无序数组中的数据能映射到对应的