【算法】————10、基数排序

本文详细介绍了基数排序算法,包括其工作原理、实现步骤及代码示例。基数排序是一种非比较型整数排序算法,通过分别排序和收集的方式进行,适用于数据范围较小的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法简介

基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再 按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。

算法描述和实现

具体算法描述如下:

  • <1>.取得数组中的最大数,并取得位数;
  • <2>.arr为原始数组,从最低位开始取每个位组成radix数组;
  • <3>.对radix进行计数排序(利用计数排序适用于小范围数的特点);

Javascript代码实现:

/**
 * 基数排序适用于:
 *  (1)数据范围较小,建议在小于1000
 *  (2)每个数值都要大于等于0
 * @author xiazdong
 * @param  arr 待排序数组
 * @param  maxDigit 最大位数
 */
//LSD Radix Sort

function radixSort(arr, maxDigit) {
    var mod = 10;
    var dev = 1;
    var counter = [];
    console.time('基数排序耗时');
    for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
        for(var j = 0; j < arr.length; j++) {
            var bucket = parseInt((arr[j] % mod) / dev);
            if(counter[bucket]== null) {
                counter[bucket] = [];
            }
            counter[bucket].push(arr[j]);
        }
        var pos = 0;
        for(var j = 0; j < counter.length; j++) {
            var value = null;
            if(counter[j]!=null) {
                while ((value = counter[j].shift()) != null) {
                      arr[pos++] = value;
                }
          }
        }
    }
    console.timeEnd('基数排序耗时');
    return arr;
}
var arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48];
console.log(radixSort(arr,2)); //[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

JAVA:

package sort;

public class RadixSort {
private static void radixSort(int[] array,int d)
{
    int n=1;//代表位数对应的数:1,10,100...
    int k=0;//保存每一位排序后的结果用于下一位的排序输入
    int length=array.length;
    int[][] bucket=new int[10][length];//排序桶用于保存每次排序后的结果,这一位上排序结果相同的数字放在同一个桶里
    int[] order=new int[length];//用于保存每个桶里有多少个数字
    while(n<d)
    {
        for(int num:array) //将数组array里的每个数字放在相应的桶里
        {
            int digit=(num/n)%10;
            bucket[digit][order[digit]]=num;
            order[digit]++;
        }
        for(int i=0;i<length;i++)//将前一个循环生成的桶里的数据覆盖到原数组中用于保存这一位的排序结果
        {
            if(order[i]!=0)//这个桶里有数据,从上到下遍历这个桶并将数据保存到原数组中
            {
                for(int j=0;j<order[i];j++)
                {
                    array[k]=bucket[i][j];
                    k++;
                }
            }
            order[i]=0;//将桶里计数器置0,用于下一次位排序
        }
        n*=10;
        k=0;//将k置0,用于下一轮保存位排序结果
    }
    
}
public static void main(String[] args)
{
    int[] A=new int[]{73,22, 93, 43, 55, 14, 28, 65, 39, 81};
    radixSort(A, 100);
    for(int num:A)
    {
        System.out.println(num);
    }
}
}

算法分析

  • 最佳情况:T(n) = O(n * k)
  • 最差情况:T(n) = O(n * k)
  • 平均情况:T(n) = O(n * k)

基数排序有两种方法:

  • MSD 从高位开始进行排序
  • LSD 从低位开始进行排序

基数排序 vs 计数排序 vs 桶排序

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

  1. 基数排序:根据键值的每位数字来分配桶
  2. 计数排序:每个桶只存储单一键值
  3. 桶排序:每个桶存储一定范围的数值

 

数据结构中的排序算法是指一种将一串数据按照特定顺序(通常是升序或降序)排列的方法。常见的排序算法有多种,每种都有其特点和适用场景: 1. **冒泡排序**(Bubble Sort):简单直观,通过不断交换相邻元素使得较大值逐渐“浮”到数组顶部。效率较低,适用于小规模数据。 2. **选择排序**(Selection Sort):每次从未排序部分找出最小(大)元素,放到已排序部分的末尾。不稳定,对大规模数据效率不高。 3. **插入排序**(Insertion Sort):类似于打扑克牌,将每个元素逐个插入到已排序的部分的适当位置。效率随着数据有序程度提高而提升。 4. **快速排序**(Quick Sort):采用分治策略,选取一个基准元素,将序列分为两部分,一部分小于基准,另一部分大于基准,然后递归地对这两部分进行排序。平均性能好,是一种常用的高效排序法。 5. **归并排序**(Merge Sort):同样基于分治,将数组分成两个子数组,分别排序后再合并。稳定,但需要额外的空间存储。 6. **堆排序**(Heap Sort):利用堆这种数据结构特性,构建最大堆或最小堆进行排序。原地操作,效率较高。 7. **计数排序**(Counting Sort):针对非负整数,统计每个元素出现次数,再根据次数重构有序序列。时间复杂度低至线性,但只能处理整数范围有限的情况。 8. **基数排序**(Radix Sort):按位数从最低位到最高位进行排序,适合数字类型的整数排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FLy_鹏程万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值