(1)计数排序算法思想
伪计数排序(被坑了,乍一看有点计数的思想,但是时间复杂度O(N^2),空间复杂度O(n),真的侮辱智商)
这是某博主的提供的思路
【 对每一个输人元素x,确定小于x 的元素个数。 利用这一信息,就 可以直接把x放到它在输出数组中的位置上了。 例如,如果有17个元素小于x,则x就应该在第18个输出位置上。 当有几个元素相同时,这一方案要略做修改。 因为不能把它们放在同一个输出位置上。】
正确的计数排序算法及桶排序算法
计数排序的适用范围:待排序的元素在某一个范围[MIN, MAX]之间 。
计数排序的时间复杂度:O(m+n)
计数排序的空间复杂度:O(maxValue-minValue+1)
遍历一遍数组A,在辅助数组上相应位置增加(如遇到5,那么辅助数组aux[5]++)
代码实现还是比较简单的
注意:很多博客往往将计数排序称为桶排序,实际上不严谨
桶排序是计数排序的变种,它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。
(1)将待排序元素划分到不同的桶。先扫描一遍序列求出最大值 maxV 和最小值 minV ,设桶的个数为 k ,则把区间 [minV, maxV] 均匀划分成 k 个区间,每个区间就是一个桶。将序列中的元素分配到各自的桶。
对每个桶内的元素进行排序。可以选择任意一种排序算法。
(2)将各个桶中的元素合并成一个大的有序序列。
假设数据是均匀分布的,则每个桶的元素平均个数为 n/k 。假设选择用快速排序对每个桶内的元素进行排序,那么每次排序的时间复杂度为 O(n/klog(n/k)) 。总的时间复杂度为 O(n)+O(m)O(n/klog(n/k)) = O(n+nlog(n/k)) = O(n+nlogn-nlogk 。当 k 接近于 n 时,桶排序的时间复杂度就可以金斯认为是 O(n) 的。即桶越多,时间效率就越高,而桶越多,空间就越大。
基数排序
按位来排序
- 将所有待排序整数(注意,必须是非负整数)统一为位数相同的整数,位数较少的前面补零。一般用10进制,也可以用16进制甚至2进制。所以前提是能够找到最大值,得到最长的位数,设 k 进制下最长为位数为 d 。
- 从最低位开始,依次进行一次稳定排序。这样从最低位一直到最高位排序完成以后,整个序列就变成了一个有序序列。
举个例子,有一个整数序列,0, 123, 45, 386, 106,下面是排序过程:
第一次排序,个位,000 123 045 386 106,无任何变化
第二次排序,十位,000 106 123 045 386
第三次排序,百位,000 045 106 123 386
最终结果,0, 45, 106, 123, 386, 排序完成。
计数排序可能会遇到吧,桶排序一般不会遇到要写代码的情况,了解其思想即可。
对了,我在夏令营面试的时候遇到过这样的问题
老师:看你学过C语言,那我问你几个问题(我一个都没答上来)
(1)如何不用辅助变量,交换两个变量的值
答案:
a=a+b,b=a-b,a=a-b
(2) 如何时间复杂度O(n)排序
答案:
比较类型的(或者是通用排序算法)排序最快要O(NlogN)
但是计数排序时间复杂度可以达到O(n)