【思维】基数排序
2011-04-17 23:35 BlueDream 阅读(1825) 评论(0) 编辑 收藏 举报算法定义
基数排序(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 = [333, 956, 175, 345, 212, 542, 99, 87];
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 = [333, 956, 175, 345, 212, 542, 99, 87];
alert(radixSort(arr, 4))