代码改变世界

【思维】基数排序

2011-04-17 23:35 by BlueDream, ... 阅读, ... 评论, 收藏, 编辑

算法定义

基数排序(Radix sort)是一种排序算法,它是这样实现的:
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零. 然后, 从最低位开始, 依次进行一次排序.这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.
基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

算法描述

基数排序的简单描述就是将数字拆分为个位十位百位,每个位依次排序。因为这对算法稳定要求高。所以我们对数位排序用到上一个排序方法计数排序

因为 基数排序 要经过d (数据长度)次排序, 每次使用计数排序, 计数排序的复杂度为 ⊙(n),  d 相当于常量,和N无关, 所以基数排序也是 ⊙(n)

基数排序虽然是线性复杂度, 即对n个数字处理了n次,但是每一次代价都比较高, 而且使用计数排序的基数排序不能进行原地排序,需要更多的内存, 并且快速排序可能更好地利用硬件的缓存, 所以比较起来,像快速排序这些原地排序算法更可取。

但是基数排序有个优点是:它是稳定的(PS: 归并排序也是稳定的)

源码描述

/* 计数排序包装 */
function stableSort(arr, k/*最多不超过4位*/) {
    
var re = [];
    
var C = []; 

    
for (var i = 0; i <= 9; i++) {
        C[i] 
= 0;
    }
    
    
for (var i = 0, l = arr.length; i < l; i++) {
        
var d = getIndex(arr[i], k);
        C[d]
++;
    }

    
for (var i = 1; i <= 9; i++) {
        C[i] 
= C[i] + C[i-1];
    }

    
for (var i = arr.length-1; i >= 0; i--) {
        
var d = getIndex(arr[i], k);
        re[C[d]
-1= arr[i];
        C[d]
--;
    }
    
return re;
}


/*截取指定位数的值*/
function getIndex(a, k) {
    
while (a != 0 && k != 0) {
        a 
/= 10;
        k--;
    }
    
return Math.floor(a % 10);
}

function radixSort(arr, d/*arr中的数字不会长于d位*/) {
    
for (var i = 0; i < d; i++) {
        arr 
= stableSort(arr, i); /*依次对各位数字排序(直接用计数排序的变体)*/
    }
    
return arr;
}

var arr  = [3339561753452125429987];

alert(radixSort(arr, 4))