本博文源于浙江大学《数据结构》,今天跟随姥姥学习基数排序,基数排序是我目前写的最复杂的排序了,复杂的方面主要是以下方面:
基数排序原理
基数排序的复杂是因为由桶排序的推广,所谓的桶排序是将可能的取值作为桶,然后将数据放到桶里,最后将桶里的内容做个简单的收集就变成有序的数列了。基数排序继承这一思想,分为主位优先和次位优先。就那扑克牌作排序为例
次位优先
先以最次位关键字建立桶,按面值建立13个桶,分别有规则放进去,最后所有牌收集,再按花色建桶,然后再收集。最后完美序列
主位优先
先按花色建立桶,然后再按面值建立桶。
总结
主位优先是分而治之,次位优先是按照分配收集,简单粗暴。所以一般情况次位优先更有效率,下面附上源码及测试用例
测试用例
int a[10] = {64,8,216,512,27,729,0,1,343,125};
效果图
附上代码
//sort桶排序次位优先.c
#include<stdio.h>
#include<stdlib.h>
#define MaxDigist 4
#define Radix 10
typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {
int key;
struct Node* next;
};
struct HeadNode {
PtrToNode head,tail;
};
typedef struct HeadNode Bucket[Radix];
int GetDigit(int X,int D)
{
int d,i;
for(i=1;i<=D;i++) {
d = X % Radix;
X /= Radix;
}
return d;
}
void LSDRadixSort(ElementType A[], int N)
{
int D,Di,i;
Bucket B;
PtrToNode tmp,p,List = NULL;
for(i=0;i<Radix;i++)
B[i].head = B[i].tail = NULL;
for(i=0;i<N;i++) {
tmp = (PtrToNode)malloc(sizeof(struct Node));
tmp->key = A[i];
tmp->next = List;
List = tmp;
}
//开始排序
for(D=1;D<=MaxDigist;D++) {
p = List;
while(p) {
Di = GetDigit(p->key,D);
tmp = p;
p = p->next;
tmp->next =NULL;
if(B[Di].head == NULL)
B[Di].head = B[Di].tail = tmp;
else{
B[Di].tail->next = tmp;
B[Di].tail = tmp;
}
}
List = NULL;
for(Di = Radix-1;Di>=0;Di--) {
if(B[Di].head) {
B[Di].tail->next = List;
List = B[Di].head;
B[Di].head = B[Di].tail = NULL;
}
}
}
for(i=0;i<N;i++) {
tmp = List;
List = List->next;
A[i] = tmp->key;
free(tmp);
}
}
void Print_Array(ElementType A[],int N)
{
printf("\n");
for(int i=0;i<N;i++)
printf("%d ",A[i]);
}
int main()
{
int a[10] = {64,8,216,512,27,729,0,1,343,125};
LSDRadixSort(a,10);
Print_Array(a,10);
return 0;
}