摘要:(1)基数排序法是建立在桶式排序的基础之上,而桶式排序的缺点就是不方便计算数值很大的数组(元素个数不一定多)。利用基数排序可以解决这个问题
(2)基数排序的基本思想是将元素的每一位都拿出来进行比较,比较的顺序是从低位到高位。第一次比较之后,再将比较过的数据取出下一位进行比较(注意:比较的是某一位(或者多位)的大小,但是存放的整个元素)。
(3)这样,如果两个元素a,b的第1-i位相同,而第i+1位a>b,则a会排在b的前面,这样当他们第i+2位也相同的时候,a任然排在b前面(这是由前面的比较决定的)相当于进行多次桶式排序,每一次都在前一次的基础上进行。
如图:
(4)采用的数据结构:如果采用一个二维的数组,那么就需要10*N的空间(N是元素个数).而实际上我们只需要N个空间。因此采用链表,定义一个链表数组(数组成员是链表),这样每一个成员所需要的空间就可以灵活的决定。
#include "stdafx.h"
#include "stdlib.h"
#include "malloc.h"
#include "time.h"
#include "math.h"
#include "malloc.h"
typedef struct Node *PtrtoNode;
#define Number_stu 1000//1000个学生
struct Node
{
int Element;
PtrtoNode Next;
};
typedef PtrtoNode List;
struct student
{
List L;
};
List Create(List L, int x)//用来创建一个单向链表
{
List P = L;
while(P ->Next!=NULL)
P = P->Next;
P->Next = (List)malloc(sizeof( struct Node));
P = P->Next;
P->Element = x;
P->Next = NULL;
return L;
}
int Digit(int number , int k)//获得第 3*(k-1)+1 到3*k位
{
int result = 0;
for (int i = 1;i <= 3*(k-1);i++)
number /= 10;
for (int i = 1;i<=3;i++){
result += pow((long double) 10,i-1)*(number%10);
number /= 10;
}
return result;
}
List Delete(List L,List P)//删除链表节点,返回删除节点的后一个;有可能返回随机地址
{
List temp;
while(L->Next!=NULL&&L->Next!= P)
L = L->Next;
if (L->Next==NULL)
return NULL;
temp = L->Next;
L->Next = temp->Next;
free(temp);
return L->Next;
}
int _tmain(int argc, _TCHAR* argv[])
{
List tmep;
int m;
int Number_student[Number_stu];
for (int i = 0;i<=Number_stu-1;)
Number_student[i++] = 1001*Number_stu - i;
//创建1000个bucket
student Bucket[1000];
for (int i =0;i<=999;i++)
{
Bucket[i].L = (List)malloc(sizeof( Node));
Bucket[i].L->Next = NULL;
}
int x = 0;
for (int i = 1;i<=3;i++)
{
//分3次排序,每次三位
for (int k = 0;k<=Number_stu-1;k++)
{
//获取某三位 : x (0,999)
x = Digit(Number_student[k],i);
Create(Bucket[x].L,Number_student[k]);
}
//覆盖原数组
m = 0;
List P ;
for(int i = 0;i<=999;i++)
{
P = Bucket[i].L->Next;
while(P!=NULL){
Number_student[m++] = P->Element;
P = Delete(Bucket[i].L,P);//获得下一个节点
}
}
}
return 0;
}