提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法,而且当O(k)>O(nlog(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(nlog(n)), 如归并排序,堆排序)
通俗讲,就是利用额外空间将数组中每个元素进行次数统计,再将统计后的结果按统计数组下标和统计次数复原原数组,得到排序结果 1.遍历整个数组,找出数组范围(找到最大值) 2.建立和数组范围一样大的统计数组,将每个数字放入对应的统计数组中 3.遍历统计数组,输出结果
进阶: 解决两个问题:1.数组不是从0开始,如{95,91,92,91,98,96} 2.排序的相对稳定性(相同元素的前后顺序)
int* stableCountSort(int *arrary, int len) { //1.得到数列中最大,最小值 int max = INT_MIN; int min = INT_MAX; for (int i = 0; i < len; ++i) { if (arrary[i] > max) { max = arrary[i]; } if (arrary[i] < min) { min = arrary[i]; } } //2.计算差值,求出统计数组长度 int d = max - min; int* countArrary = new int[d + 1]; for (int i = 0; i < d + 1; ++i) { countArrary[i] = 0; } //3.遍历数组,获取统计数组值 for (int i = 0; i < len; ++i) { countArrary[arrary[i] - min]++; } //4.统计数组变形,后面元素等于前面元素之和 int sum = 0; for (int i = 0; i < d + 1; ++i) { sum += countArrary[i]; countArrary[i] = sum; } //5.倒序遍历原始数组,从统计数组找到正确位置,输出到结果数组 int* sortedArrary = new int[len]; for (int i = len - 1; i >= 0; --i) { sortedArrary[countArrary[arrary[i] - min] - 1] = arrary[i]; countArrary[arrary[i] - min]--; } return sortedArrary; }1.当数列最大最小值差距过大时,并不适用于计数排序
比如给定20个随机整数,范围在0到1亿之间,此时如果使用计数排序的话,就需要创建长度为1亿的数组,不但严重浪费了空间,而且时间复杂度也随之升高。
2.当数列元素不是整数时,并不适用于计数排序
如果数列中的元素都是小数,比如3.1415,或是0.00000001这样子,则无法创建对应的统计数组,这样显然无法进行计数排序。
正是由于这两大局限性,才使得计数排序不像快速排序、归并排序那样被人们广泛适用。