十大排序算法(JavaScript实现 )- 计数排序 Count Sort

131 阅读1分钟
  1. 十大排序算法(JavaScript实现 )- 冒泡排序 Bubble Sort

  2. 十大排序算法(JavaScript实现 )- 选择排序 Selection Sort

  3. 十大排序算法(JavaScript实现 )- 插入排序 Insertion Sort

  4. 十大排序算法(JavaScript实现 )- 希尔排序 Shell Sort

  5. 十大排序算法(JavaScript实现 )- 快速排序 Quick Sort

  6. 十大排序算法(JavaScript实现 )- 归并排序  Merge Sort

  7. 十大排序算法(JavaScript实现 )- 计数排序 Count Sort

  8. 十大排序算法(JavaScript实现 )- 桶排序 Bucket Sort

  9. 十大排序算法(JavaScript实现 )- 基数排序 Radix Sort

  10. 十大排序算法(JavaScript实现 )- 堆排序 Heap Sort

概念

计数排序是一个排序时不比较元素大小的排序算法。

算法原理

  1. 比如我们有如下原始数组:[88,82,82,86,82,88,88,85,85,84]

图片.png

  1. 紧接着,分别求出原始数组的最小值和最大值:8288,求出计数数组长度7
// 1. 先求出最大值和最小值
let min = arr[0]
let max = arr[1]
for(let i = 1; i < arr.length; i++) {
    if (arr[i] < min) {
        min = arr[i]
    }
    if (arr[i] > max) {
        max = arr[i]
    }
}
const length = max - min + 1
  1. 初始化一个长度为7的计数数组,值均初始化为0

图片.png

  1. 遍历原始数组,计数数组下标对应的值得个数,比如0对应82共有3个,那么temp[0]=3
// 填充计数数组
const temp = Array(length).fill(0)
for (let i = 0; i < arr.length; i++) {
  temp[arr[i] - min]++
}

图片.png

  1. 将数组变形,使计数数组的元素等于加上前面元素的值之和
// 计数数组形变,后面的元素等于前面的元素之和
let sum = 0
for (let i = 0; i < length; i++) {
  sum += temp[i]
  temp[i] = sum
}

此时计数数组结果为: 图片.png

  1. 倒序遍历原始数组 先声明一个输出数组,然后倒序遍历原始数组:
    1. 取出最后一个数84,此数下标为9,获取其对应的计数数组的的下标[arr[i] - min]:84-82:2;
    1. 计数数组的前一个的下标对应的值是temp[[arr[i] - min]]:4,即84对应的排序是4-1;
    1. 每取出一个,当前数对应的计数数组下标[arr[i] - min]要-1,即此时temp[2]--,变为3

图片.png

let result = []
for (let i = 0; i < arr.length; i++) {
    result[temp[arr[i] - min] - 1] = arr[i]
    temp[arr[i] - min]--
}

算法代码

function countSort(arr) {
  // 1. 先求出最大值和最小值
  let min = arr[0]
  let max = arr[1]
  for(let i = 1; i < arr.length; i++) {
    if (arr[i] < min) {
      min = arr[i]
    }
    if (arr[i] > max) {
      max = arr[i]
    }
  }
  const length = max - min + 1

  // 填充计数数组
  const temp = Array(length).fill(0)
  for (let i = 0; i < arr.length; i++) {
    temp[arr[i] - min]++
  }
  // 计数数组形变,后面的元素等于前面的元素之和
  let sum = 0
  for (let i = 0; i < length; i++) {
      sum += temp[i]
      temp[i] = sum
  }
  
  let result = Array(arr.length)
  for (let i = arr.length - 1; i >=0; i--) {
    result[temp[arr[i] - min] - 1] = arr[i]
    temp[arr[i] - min]--
  }
  return result
}