Radix按JavaScript排序

时间:2010-09-28 21:07:11

标签: javascript sorting radix-sort

我想出了以下内容,但可以预见它不起作用。

var t = new Array(a.length);
var r = 4;
var b = 64;

var count = new Array(1<<r);
var pref = new Array(1<<r);

var groups = Math.ceil(b / r);

var mask = (1 << r) - 1;

var shift = 0;
for(var c = 0; c < groups; c++)
{
    shift += r;

    for(var j = 0; j < count.length; j++)
    {
        count[j] = 0;
    }

    for(var i = 0; i < a.length; i++)
    {
        count[ (a[i] >> shift) & mask ]++;
    }

    pref[0] = 0;

    for(var i = 0; i < count.length; i++)
    {
        pref[i] = pref[i-1] + count[i-1];
    }

    for(var i = 0; i < a.length; i++)
    {
        t[ pref[ (a[i] >> shift) & mask ]++ ] = a[i];
    }

    for(var i = 0; i < a.length; i++)
    {
        a[i] = t[i];
    }
    // a is sorted?
}

2 个答案:

答案 0 :(得分:6)

这个循环基本上是一样的,用更简单的Javascript-y方式:

for (var div = 1, radix = 16; div < 65536 * 65536; div *= radix) {
  var piles = [];

  for (var i = 0; i < a.length; ++i) {
    var p = Math.floor(a[i] / div) % radix;
    (piles[p] || (piles[p] = [])).push(a[i]);
  }

  for (var i = 0, ai = 0; i < piles.length; ++i) {
    if (!piles[i]) continue;
    for (var pi = 0; pi < piles[i].length; ++pi)
      a[ai++] = piles[i][pi];
  }
}

这个循环不是像C程序员那样,而是构建一个列表列表,每个可能的4位值都有一个列表。我避免使用位移操作符,因为这是Javascript,当他们工作时,当数字变大时,事情变得有趣。

从“a”中每个值的低4位开始,代码将“a”的元素复制到其中一个“桩”的末尾,即对应于4位值的那一个。然后它收集堆并重建“a”,从低4位为0,然后是1等的所有值开始。(显然会有一些间隙,所以跳过这些。)在每次迭代结束时在整个循环中,除数乘以基数,以便检查下一组4位。

一旦除数耗尽了可用的整数范围,就完成了。

请注意,这仅适用于数字。用负数做这个有点奇怪;将负数删除到单独的数组中,翻转符号,排序,然后反转可能更容易。对正数进行排序,然后最后将反转的负数(将符号再次翻转)粘贴到已排序的正数的前面。

答案 1 :(得分:0)

这个

for(var i = 0; i < count.length; i++) 
{ 
    pref[i] = pref[i-1] + count[i-1]; 
} 

是一个问题,因为在第一次迭代中,i为零,因此pref[ 0 - 1 ]无法正常工作。

我没有参考radix排序方便地确定你应该在这里做什么。