深入浅出---基数排序

作为一个没有学过算法的小白,说一下自己对基数排序的了解(可能理解不到位,以后深入理解的话再来更改)

首先呢说一下,基数排序的思想是啥。

基数排序呢有两种方法,一种是低位优先,一种是高位优先,

看书上的例子:有一副扑克牌:(先随意规定一个优先级)

花色:梅花<方块<红桃<黑桃

面值:A<2<3<.......<J<Q<K

高位优先:先把所有的排按照花色优先级排列,然后在按照面值从小到大去排列。也就是说,你有四个空,你把所有的牌放到四个空里面,每个空有13张牌。

低位优先:先把所有的排按照面值排列好,然后在按照花色优先级去排列。也就是说你先分13个空,然后你再去把所有的牌一一的放到13个空相对的空。(通过反复的进行分配和收集操作完成排序)

链式基数排序就是基于低位优先的思想排的。

举个栗子:

有8个数字,{965,23231,5556,8748,485,57,236,911}

有五位数,有三位数,有两位数

每个数字有“个十百千”位,砸门按照低位优先思想,也就说哦们先看个位的数字,我们先设置10个桶,把个位是1的数放到“1”的桶。

这就是第一遍排,

第二遍呢,就是比较十位,

第三遍就是比较百位,知道所有的数字的那一位都等于0,停止比较。

程序:我们可以先写第一遍排序:

#include<stdio.h>
#include<stdlib.h>
//获取个十百位的数字
int getNum(int num,int pos){
int temp=1;
for(int i=1;i<pos-1;i++){
temp*=10;
}
return (num/temp)%10;
}
int main(void){
int a[8]={965,23231,5556,8748,485,57,236,911};
//申请数组
int *Array[10];
//因为位数上可能出现0-9这些数字,所以申请十个桶
for(int i=0;i<10;i++){
Array[i]=(int*)malloc(sizeof(int)*(9));
Array[i][0]=0;//第一个存放个数 

        //有八个数字,循环八次

for(int i=0;i<8;i++){
int num=getNum(a[i],1);//得到八个数字的位数
int index=++Array[num][0];//桶的第一个元素里的值放的是该桶有多少个数字,为了后面循环放入数组中做准备
Array[num][index]=a[i];//num 就是你桶的位置,index是你是该桶的第几个元素
}
//收集
for(int i=0,j=0;i<10;i++){//这里的10 可以随意更改,因为你一个数字的位数不确定
for(int k=1;k<=Array[i][0];k++)   //k是循环该桶数字的一个条件
a[j++]=Array[i][k];
Array[i][0]=0; //恢复桶第一个元素的值,因为比较百位的时候,桶里的值要重新填,所以要恢复

//循环输出
for(int i=0;i<8;i++){
printf("%d\t",a[i]);
}
printf("\n");

循环百位,千位,不过就是给他分配与收集的过程加一个循环

#include<stdio.h>
#include<stdlib.h>
//获取值
int getNum(int num,int pos){
int temp=1;
for(int i=1;i<pos-1;i++){
temp*=10;
}
return (num/temp)%10;
}
int main(void){
int a[8]={965,23231,5556,8748,485,57,236,911};
//申请数组
int *Array[10];

for(int i=0;i<10;i++){
Array[i]=(int*)malloc(sizeof(int)*(9));
Array[i][0]=0;//第一个存放个数 

//从个位开始比较
for(int pos=1;pos<=10;pos++){
for(int i=0;i<8;i++){
int num=getNum(a[i],pos);
int index=++Array[num][0];
Array[num][index]=a[i];
}


//收集
for(int i=0,j=0;i<10;i++){
for(int k=1;k<=Array[i][0];k++)
a[j++]=Array[i][k];
Array[i][0]=0;
}
for(int i=0;i<8;i++){
printf("%d\t",a[i]);
}
printf("\n"); 



呃呃呃,我理解的基数排序就是这样。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值