基数排序法

摘要:(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值