基数排序算法

1、基本思想

基数排序是一种非比较型整数排序算法,其基本思想是将整数按位数切割成不同的数字,然后按每个位数分别比较。

具体来说,它是基于对每一位数字进行桶排序(或计数排序等稳定排序算法作为内层排序)来实现整体排序的。从最低有效位(个位)开始,依次对每一位数字进行排序,经过多次排序后,最终使得整个序列有序。

2、算法步骤

2.1、算法步骤描述:

假设为升序排序

1、首先确定待排序序列 arr 中最大的元素得出元素的位数 N,位数 N 决定了基数排序需要进行 N 轮;

2、定义一个二维数组 bucket 作为桶(bucketmn表示第 m 个桶的第 n 个元素)。对于整数排序,由于一位数有 10 种可能(0~9),因此需要10 个桶 ;又因为arr 中可能所有元素某一位完全相同(此时所有元素都在一个桶中),因此每个桶最小空间要能存储待排序序列arr的所有元素(序列arr的大小这里用arr.length来表示)。故有int bucket10arr.length

3、由于需要对每个桶多次存取数据,因此还需定义一个一维数组bucketCount用作记录每个桶中元素的个数(如bucketCount2的值代表着第三个桶中当前的元素数量);

4、第一轮开始,遍历待排序序列 arr ,求得每个元素的个位数然后将元素放入到其个位数对应的桶中。元素放置完毕之后,再从桶中按照次序读取数据覆盖到 arr ;

5、第二轮开始,首先清空计数桶中的元素,然后遍历最新的 arr,求得每个元素的十位数,然后将元素放入到其十位数对应的桶中。元素放置完毕后,再从桶中按照次序读取数据覆盖 arr ;

6、循环执行步骤 5,直到总计执行了N轮(最大元素的位数决定),然后从桶中读出数据覆盖到arr中,此时arr中便是最终排序结果。

2.2、基数排序算法动态演示图:

基数排序

动态演示图来源网站URL:​​​​​​https://visualgo.net

3、代码实现

c语言代码实现如下:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define N 10
void sort(int arr[])
{
    if (N <= 0)//数组无元素,无需排序
        return;
    int i,j,k = 0;
    int max_value = arr[0];
    for(i = 0; i < N; i++)//找出最大值
    {
        if(arr[i] > max_value)
        {
            max_value = arr[i];
        }
    }
    int d = 0;
    while(max_value)//找出最大数的最高位位数,确定排序轮数
    {
        max_value /= 10;
        d++;
    }
    int bucket[10][N];//定义桶,行标根据一位数的可能性确定,列表根据待排序数组大小确定
    int bucketCount[10] = {0};//定义桶的计数器,存放每个桶的数据个数
    for(i = 0; i < d; i++)//开始排序
    {
        memset(bucketCount,0,sizeof(bucketCount));//清空桶元素
        for(j = 0; j < N; j++)//放入桶中
        {
            int num = 1;
            int i2 = i;//不能直接用i来进行--操作,i是外层循环的条件
            while(i2--)
            {
                num = num * 10;
            }
            bucket[arr[j]/num%10][bucketCount[arr[j]/num%10]++] = arr[j];
        }
        int index = 0;
        for(j = 0; j < 10; j++)//从桶中读取数据,覆盖到原数组
        {
            for(k = 0; k < bucketCount[j]; k++)
            {
                arr[index++] = bucket[j][k];
            }
        }
    }
}
int main(int argc, char *argv[])
{
    srand(time(NULL));
    int a[N];
    int i;

    puts("排序前数组为:");
    for(i = 0; i < N; i++)
    {
        a[i] = rand()%100;//为数组随机赋值
        printf("%d ",a[i]);//输出排序之前数组值
    }
    puts("");

    sort(a);//排序

    puts("排序后的数组为:");
    for(i = 0; i < N; i++)
    {
        printf("%d ",a[i]);//输出排序之后的数组值
    }
    puts("");

    return 0;
}

4、时间复杂度和空间复杂度

时间复杂度:基数排序的时间复杂度取决于数据的范围和数位,时间复杂度为O(d(n+k)),d为数据的最大数位,n是待排序元素的个数,k是每一位数字可能的取值范围。

空间复杂度:O(n+k),n是待排序元素的个数,k是每一位数字可能的取值范围。

稳定性:稳定。

5、适用情况

1、待排序数据是整数且数据范围和位数相对固定的情况。

2、数据量比较大,但每一位数字的取值范围不是特别大的情况。

3、当数据的最高位有优先排序的意义时。

相关推荐
装不满的克莱因瓶8 分钟前
掌握语义分割经典模型 FCN——从像素分类到端到端分割的奠基之作
人工智能·python·深度学习·算法·机器学习·分类·数据挖掘
学计算机的计算基12 分钟前
链表算法上篇:LeetCode 206/234/141/142/160/21 题解与易错点
java·笔记·算法·链表
大白话_NOI16 分钟前
【洛谷 P2678】 [NOIP2015 提高组] 跳石头 超详细题解
c++·算法
xwz小王子19 分钟前
ICRA 2026深度观察:全栈闭环成标配,中国具身智能势力显著崛起
大数据·人工智能·算法
孬甭_20 分钟前
深入解析归并排序:稳定高效的分治典范
算法·排序算法
DXM052128 分钟前
第14期|高阶分割模型:Transformer/SegFormer遥感应用
人工智能·python·神经网络·算法·计算机视觉·cnn·ageo
Kurisu_红莉栖1 小时前
前缀和的另外一种用法,前缀和分解
算法
88号技师1 小时前
2026年2月一区SCI-交叉传播优化算法Propagation Alongside Crossover-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
悠仁さん1 小时前
数据结构 图(代码实现篇 C语言版)
数据结构·算法·图论
aini_lovee1 小时前
多智能体粒子群优化(Multi-Agent Particle Swarm Optimization, MAPSO)
算法