基数排序(C语言)

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数

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

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

  • 基数排序:根据元素的每位数字来分配桶;
  • 计数排序:每个桶只存储单一键值;
  • 桶排序:每个桶存储一定范围的数值;

基数排序动图演示

image
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
//定义基数为10进制
#define radix 10
//交换数值
void swap(int *a,int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
//打印数组
void printArray(char msg[],int arr[],int len){
    printf("%s:",msg);
    for (int i = 0; i < len; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
}
//基数排序
void radix_sort(int a[],int len){
    int maxvalue=a[0],minvalue=a[0];
    for(int x=0;x<len;x++){
        maxvalue=a[x]>maxvalue?a[x]:maxvalue;
        minvalue=a[x]<minvalue?a[x]:minvalue;
    }
    int* temp = (int*)malloc(len*sizeof(int));
    //获取最大位数
    int n=1;
    int d = maxvalue-minvalue;
    while(d>=10){
        d=d/10;
        n++;
    }
    printf("总遍历位数:%d,最小值:%d,最大值:%d\n",n,minvalue,maxvalue);
    //要获取的位
    int divide=1;
    for(int i=1;i<=n;i++){
        //初始化计数器
        int counter[radix]={0};
        for(int j=0;j<len;j++){
            //找出a[j]相对minvalue值的对应的位divide的值
            int pos = ((a[j]-minvalue)/divide)%radix;
            //a[j]换算成计数器数组下标pos并自增
            counter[pos]++;
        }
        //使用累加(counter[n]=counter[n]+counter[n-1],有点类似斐波那契数列)计算出元素所在位置,保证结果有序
        for(int j=1;j<10;j++){
            counter[j]=counter[j]+counter[j-1];
        }
        //倒序遍历数组a,可以保持结果稳定性
        for(int j=len-1;j>=0;j--){
            //将a[j]映射到计数器下标pos,counter[pos]就是a[j]在新数组的位置
            int pos=((a[j]-minvalue)/divide)%radix;
            //获取元素位置mappos,--counter[pos]:每放一个元素到数组temp,counter[pos]值自减,保证结果稳定有序
            int mappos=(--counter[pos]);
            temp[mappos]=a[j];
        }
        //把temp有序数组赋值给a
        for(int j=0;j<len;j++){
            a[j]=temp[j];
        }
        printf("遍历位数%d:\n",divide);
        for(int j=0;j<len;j++){
            printf("a[%d]=%d,a[%d]-%d=%d\n",j,a[j],j,minvalue,a[j]-minvalue);
        }
        printf("\n");
        //获取数值的下个位,比如个位数,下个是十位数
        divide=divide*radix;
    }
    free(temp);
}
int main()
{
    int len=10;
    int arr[len];
    srand((unsigned)time(NULL));
    //随机生成长度为"len"的数组
    for(int i=0;i<len;i++){
        arr[i]=rand()%200;
    }
    printArray("未排序前",arr,len);
    radix_sort(arr,len);
    printArray("基数排序",arr,len);
    //防止windows下控制台窗口闪退
    int s;
    scanf("%d",&s);
    return 0;
}

运行结果:

未排序前:126 36 76 198 65 172 107 3 53 60
总遍历位数:3,最小值:3,最大值:198
遍历位数1:
a[0]=3,a[0]-3=0
a[1]=53,a[1]-3=50
a[2]=65,a[2]-3=62
a[3]=126,a[3]-3=123
a[4]=36,a[4]-3=33
a[5]=76,a[5]-3=73
a[6]=107,a[6]-3=104
a[7]=198,a[7]-3=195
a[8]=60,a[8]-3=57
a[9]=172,a[9]-3=169
遍历位数10:
a[0]=3,a[0]-3=0
a[1]=107,a[1]-3=104
a[2]=126,a[2]-3=123
a[3]=36,a[3]-3=33
a[4]=53,a[4]-3=50
a[5]=60,a[5]-3=57
a[6]=65,a[6]-3=62
a[7]=172,a[7]-3=169
a[8]=76,a[8]-3=73
a[9]=198,a[9]-3=195
遍历位数100:
a[0]=3,a[0]-3=0
a[1]=36,a[1]-3=33
a[2]=53,a[2]-3=50
a[3]=60,a[3]-3=57
a[4]=65,a[4]-3=62
a[5]=76,a[5]-3=73
a[6]=107,a[6]-3=104
a[7]=126,a[7]-3=123
a[8]=172,a[8]-3=169
a[9]=198,a[9]-3=195
基数排序:3 36 53 60 65 76 107 126 172 198

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359