计数排序——O(n)复杂度基于非比较的排序方法
2015-06-08 19:50
253 查看
基本思想
计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。计数排序的基本思想是:对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有7个元素的值小于x的值,则x可以直接存放在输出序列的第8个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。
计数排序步骤
找出待排序的数组中最大和最小的元素统计数组中每个值为i的元素出现的次数,存入数组C的第i项
对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
有三个参数:
输入数组sourceArr[], 长度为sourceArr.size(),
需要一个数组存放结果resultArr,长度大小跟sourceArr相同。
另外需要一个辅助数组,tempArr,长度大小为sourceArr中最大的元素值。
参考代码
#include "iostream" #include "vector" using namespace std; class countSort{ public: static void CSort(vector<int> sourceArr, vector<int> resultArr, const int maxNum) { vector<int> tempArr(maxNum+1);//注意分配给临时数组的大小为maxNum+1,因为后面要访问到tempArr[maxNum] for (int i = 0; i < tempArr.size(); i++) tempArr[i] = 0; for (int i = 0; i < sourceArr.size(); i++) { tempArr[sourceArr[i]]++; } //注意<=是小于等于maxNum,不要漏掉最后一个元素,开始从i=1 for (int i = 1; i <= maxNum; i++) tempArr[i] += tempArr[i - 1]; //注意tempArr[sourceArr[i]] - 1 代表的是sourceArr[i]在结果数组中的位置 //在放好之后要减一 因为有重复值相等的数 for (int i = sourceArr.size() - 1; i >= 0; i--) { resultArr[tempArr[sourceArr[i]] - 1] = sourceArr[i]; tempArr[sourceArr[i]]--; } //输出查看结果 for (int i = 0; i < resultArr.size(); i++) cout << resultArr[i] << " "; cout << endl; } int getMaxNum(vector<int> arr) { int max = 0; for (int i = 0; i < arr.size(); i++) { if (arr[i] > max) max = arr[i]; } return max; } }; int main() { vector<int> arr = { 0, 2, 12, 3, 0, 2, 3, 0, 3,5,5,2,3,7,8,4}; vector<int> ans(arr.size()); countSort csort; int max = csort.getMaxNum(arr); csort.CSort(arr, ans, max); return 0; }
时间复杂度:O(n+maxNum)
空间复杂度:O(n+maxNum)
注意:计数排序是稳定的排序方法。
1. 计数排序是有效的,如果输入数据的范围是不显著大于数字的个数。
2. 它不是一个基于比较的排序。它运行的时间复杂度为O(n)
3. 它经常被用来作为另一个排序算法像基数排序的一个子程序。
4. 计数排序可以扩展到负输入也可以。
参考资料:
http://www.cnblogs.com/ttltry-air/archive/2012/08/04/2623302.htm
http://baike.baidu.com/view/1209480.htm?wtp=tt
相关文章推荐
- 1.6jdk + eclipse + pydev搭建Python开发环境
- shell脚本循环执行mysql语句
- iOS开发中导入第三方库时不能自动补全头文件的解决方法
- HTML无刷新下载文件方法总汇
- js中获取上下文路径
- 通信系统仿真中的几个能量归一化问题
- 01背包 Codeforces Round #267 (Div. 2) C. George and Job
- jquery attr & prop
- 安卓开发黄金搭档:android-studio+Genymotion模拟器
- 【转】Debug 运行正常,Release版本不能正常运行
- 腾讯云服务器点评
- 数据需求统计常用shell命令---AWK分组求和,分组统计次数
- 从Java的Collection说起
- 函数重载概念本质
- 函数重载概念本质
- hadoop异常 java.io.IOException: Job status not available
- 一起看过的比赛
- 同一个应用程序的不同Activity可以运行在不同的进程中么?
- 数据需求统计常用shell命令
- Qt中QTableWidget用法总结