前面我们介绍了6种比较交换类的排序,现在我们看一下分类收集类的排序
计数排序一种利用空间换时间的排序办法
算法思路:
1、根据待排序集合中最大元素和最小元素的差值范围,申请额外空间;
2、遍历待排序集合,将每一个元素出现的次数记录到元素值对应的额外空间内;
3、对额外空间内数据进行计算,得出每一个元素的正确位置;
代码
**
function countSort(nums){let min = Infinity, max = -Infinityfor (const num of nums) { // 确定最大最小值min = Math.min(min, num)max = Math.max(max, num)}let store = new Array(max - min + 1).fill(0)for (const num of nums) { // 计数store[num - min]++}let p = 0, res = new Array(nums.length)for (let i = 0; i < store.length; i++) { // 逐个计数还原while(store[i]--) nums[p++] = i + min}return nums}
假如开辟的空间为k (由max(nums) - min(nums)计算得出)
时间复杂度O(n + k)
空间复杂度O(n)
我们对于普通的数字比较而言这里不需要考虑稳定性
当然如果考虑稳定性我们可以利用js的数组的特性来完成
代码
**
function countSort(nums){let min = Infinity, max = -Infinityfor (const num of nums) { // 确定最大最小值min = Math.min(min, num)max = Math.max(max, num)}let store = new Array(max - min + 1)for (const num of nums) { // 计数if(!store[num - min]) store[num - min] = [] // 当成一个队列store[num - min].push(num) // 入队列}let p = 0, res = new Array(nums.length)for (const value of store) {while(value && value.length) nums[p++] = value.shift() // 出队列}return nums}
这样对于相同一个元素而言,他们的相对输出顺序没有发生变化
