这里是传送门⇒总结:关于排序算法html
平均时间复杂度 | 最优时间复杂度 | 最差时间复杂度 | 空间复杂度 | 稳定性 | |
---|---|---|---|---|---|
计数排序 | O(n+m) | O(n+m) | O(n+m) | O(n+max) | 稳定 |
优化后 | O(n+m) | O(n+m) | O(n+m) | O(n+m) | 稳定 |
计数排序一种是“空间换时间”的排序,只能直接应用于非负整数的排序中(由于数组下标是非负整数,至关于用待排元素i做为索引,数组元素的值count[i]是待排序列中小于或者等于该下标i的元素数量)。算法
优点在对于元素取值范围m较小的待排序列的排序中,(优化后)时间复杂度是线性的Ο(n+m),快于任何键值比较排序算法。固然若是O(m)>O(nlogn)
,其效率反而不如基于键值比较的排序,若数据范围m比排序数据的数量n大不少,就不适合用计数排序。数组
虽然算法中有比较,但并不是是键值间的比较,而是经过对元素值的计数和计数值的累加来肯定的。优化
// 此处没有改变array function CountingSort(array) { var len = array.length; if (len <= 1) { return array; } var max = array[0]; var count = [], res = []; for (var i = 1; i < len; i++) { if (array[i] > max) { max = array[i]; } } var countLen = max + 1; for (var i = 0; i < countLen; i++) { count[i] = 0; } for (var i = 0; i < len; i++) { count[array[i]]++; } for (var i = 1; i < countLen; i++) { count[i] += count[i - 1]; } for (var i = len - 1; i >= 0; i--) { res[count[array[i]] - 1] = array[i]; count[array[i]]--; } return res; }
分析code
CountingSort
的S(n) = O(n + max)优化htm
count[8-偏移量8] = count[0]
中CountingSortPlus
的S(n) = O(m + n)优化版的JS实现对象
// 此处没有改变array function CountingSortPlus(array) { var len = array.length; if (len <= 1) { return array; } var min = max = array[0]; var count = [], res = []; for (var i = 1; i < len; i++) { if (array[i] > max) { max = array[i]; } if (array[i] < min) { min = array[i]; } } var countLen = max - min + 1; for (var i = 0; i < countLen; i++) { count[i] = 0; } for (var i = 0; i < len; i++) { count[array[i] - min]++; } for (var i = 1; i < countLen; i++) { count[i] += count[i - 1]; } for (var i = len - 1; i >= 0; i--) { res[count[array[i] - min] - 1] = array[i]; count[array[i] - min]--; } return res; }