目录
思想:
源码:
思想:
计数排序:用一个数组记录按原始数据中,每个数据出现的次数
 非常牛批的思路,没有用到比较
 直接对每个数据进行计数
 然后从计数的数组中,往回覆盖数据
 从左到右,依次打印次数个数据,打完数据,整个排序就好了 
 一组数据,开出和数据组相对应的count空间大小,作为映射,来对每个数据出现的次数记录
 计数排序,总的思路来说就是
 在原来数组的基础上,开出一个新的数组,空间一样
 然后,遍历原来的数组,对原来数组的每一个数据进行记录
 然后将之在count数组对应的位置+1,在遍历的过程中每遇到一次,就对该位置+1
 这才是精髓之所在!
 这是第一步
 然后进行第二步
 就是对count数组进行遍历
 对应位置出现的数据,下标是原来数据的值,count数组中记录的值是原来数据值得个数
 遍历count数组,将对应的数据覆盖回原来的数组之中


 计数排序的效率:极高!O(aN + countN)
 第一次遍历数组a,第二次遍历count
 局限性:
 1、不适合数据很分散的数据序列,更适合比较集中的数据
 2、不适合浮点数、字符串、结构体等数据排序,只适合整数
 还有一个问题:
 例如说,一组数据从99999到100000
 那么,如果是开出一组绝对映射的count数组,那么前面的99999空间就是纯粹的浪费
 所以,我们用相对映射
 最小的值放在左边
 count[a[i] - min]++;//吧对应的值放在对应的位置,非常巧妙、
 不是直接位置,而是间接位置

同时,相对映射正好可以完美的解决负数的问题
时间复杂度:O(N+range)
 空间:O(range)
 n--走n次
 --n走n-1次
在现实生活中,一般比较的都是结构体
源码:
//计数排序 void CountSort(int* a, int n) { int min = a[0], max = a[0]; for (int i = 0; i < n; i++) { if (a[i] < min) { min = a[i]; } if (a[i] > max) { max = a[i]; } } int range = max - min + 1;//左闭右闭 int* count = (int*)calloc(range, sizeof(int)); if (count == NULL) { perror("calloc fail"); return; } for (int i = 0;i < n;++i) { count[ a[i] - min]++;//对数组a对应位置的数据记录到count数组 } //排序 int i = 0; for (int j = 0;j<range;++j) { while (count[j]--) { a[i++] = j + min; } } }



















