0
点赞
收藏
分享

微信扫一扫

js排序算法详解-计数排序


​​


​​

全栈工程师开发手册 (作者:栾鹏)

​​ js系列教程5-数据结构和算法全解​​

js排序算法详解-计数排序

计数排序就是遍历数组记录数组下的元素出现过多次,然后把这个元素找个位置先安置下来,简单点说就是以原数组每个元素的值作为新数组的下标,而对应小标的新数组元素的值作为出现的次数,相当于是通过下标进行排序。

看代码:

function countingSort(array) {
  var len = array.length,
  B = [],
  C = [],
  min = max = array[0];
  console.time('计数排序耗时');
  for (var i = 0; i < len; i++) {
    min = min <= array[i] ? min : array[i];
    max = max >= array[i] ? max : array[i];
    C[array[i]] = C[array[i]] ? C[array[i]] + 1 : 1;
    console.log(C)
  }

  // 计算排序后的元素下标
  for (var j = min; j < max; j++) {
    C[j + 1] = (C[j + 1] || 0) + (C[j] || 0);
    console.log(C)
  }
  for (var k = len - 1; k >= 0; k--) {
    B[C[array[k]] - 1] = array[k];
    C[array[k]]--;
    console.log(B)
  }
  console.timeEnd('计数排序耗时');
  return B;
}
var arr = [2, 2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4, 2, 4, 6, 9, 2];
console.log(countingSort(arr)); //[1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 6, 7, 7, 8, 8, 9, 9];

这种算法的亮点就是在于利用下标存数据,利用数据存出现的次数。然后这种算法还有一个亮点就是第二个循环,计算排序后的下标,也就是说在这个地方已经把每个元素对应在排序后的数组的位置已经确定了,在第三个循环中只需要安插在对应的位置即可!

其实这里小编还另外一种算法,没有上面那种复杂,小编感觉更容易理解,仅供参考:

function countingSort(array) {
  var len = array.length,
  B = [],
  C = [],
  min = max = array[0];
  console.time('计数排序耗时');
  for (var i = 0; i < len; i++) {
    min = min <= array[i] ? min : array[i];
    max = max >= array[i] ? max : array[i];
    C[array[i]] = C[array[i]] ? C[array[i]] + 1 : 1;
  }
  for (var k = 0; k <len; k++) {
    var length = C[k];
    for(var m = 0 ;m <length ; m++){
      B.push(k);
    }
  }
  console.timeEnd('计数排序耗时');
  return B;
}
var arr = [2, 2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4, 2, 4, 6, 9, 2];
console.log(countingSort(arr)); //[1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 6, 7, 7, 8, 8, 9, 9];

思想主要是既然我们已经根据下标进行排序了,C数组的下标对应的数值就是该下标出现的次数,那何不吧该次数作为二层循环的长度遍历一遍直接推送到新得数组中呢?

附动图便于理解:

js排序算法详解-计数排序_数据结构


举报

相关推荐

0 条评论