链式基数排序

来源:互联网 发布:亿网备案域名 编辑:程序博客网 时间:2024/05/20 13:04
#include <iostream>
using namespace std;


#define MAX_NUM_OF_KEY 8        //关键字项数的最大值
#define RADIX    10            //关键字基数,此时是十进制整数的基数
#define MAX_SPACE 10000
typedef int DataType ;
typedef struct 
{
    int data;        //数据,如571
    DataType keys[MAX_NUM_OF_KEY];        //每个数据的所有关键字,571的5,7,1
    int  next;        
}SLCell;    //静态链表的节点类型


typedef struct    Sllist
{
    SLCell *R;    //静态链表的可利用空间,r[0]为头结点
    int recnum;        //静态链表的当前长度
    int keynum;        //当前数据的关键字个数
}Sllist, * SLList;    //静态链表类型


typedef int ArrType[RADIX];        //指针数组类型,声明两个指针数组,一个头指针,一个尾指针


////////////////////////////////////////////////////////////////////////////////
/*
    ArrType    front[RADIX]                                                ArrType    end[RADIX]
                |                                                |
    f[0]        |------>[930]<----------------------------------|        e[0]
                |                                                |
    f[1]        |-->                                         <--|        e[1]
                |                                                |
    f[2]        |-->                                         <--|        e[2]
                |                                                |
    f[3]        |------>[063]-->[083]<--------------------------|        e[3]
                |                                                |
    f[4]        |------>[184]<----------------------------------|        e[4]
                |                                                |
    f[5]        |------>[505]<----------------------------------|        e[5]
                |                                                |
    f[6]        |-->                                         <--|        e[6]
                |                                                |
    f[7]        |-->                                         <--|        e[7]
                |                                                |
    f[8]        |------>[278]-->[008]<--------------------------|        e[8]
                |                                                |
    f[9]        |------>[109]-->[589]-->[269]<------------------|        e[9]


*/
//////////////////////////////////////////////////////////////////////////////////


void creatList(SLList &SLL)
{


    int key, i=1,j;
    cout<<"输入要进行排序的数据:"<<endl;
    cin>>key;
    while(key!=0)
    {
        SLL->R[i].data = key;
        for(j = 1; j <= SLL->keynum; j++)
        {
            SLL->R[i].keys[j] = key % 10;
            key /= 10;
        }
        SLL->R[i-1].next=i++;
        cin>>key;
    }
    SLL->recnum = i-1;
    SLL->R[SLL->recnum].next=0;
}


void print(SLList &SLL)
{
    for(int p=SLL->R[0].next; p; p=SLL->R[p].next)
    {
        cout<<SLL->R[p].data<<"  ";
    }
    cout<<endl;
}


void distribute(SLCell *R, int i, ArrType front, ArrType end)
{
    //静态链表L的R域中记录已按(keys[0]...keys[i-1]有序)。
    //本算法按第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。
    //front[0...RADIX-1]和end[0...RADIX-1]分别指向各子表中第一个和最后一个记录。
    for(int j=0; j<RADIX; ++j)
        front[j] = 0;        //各子表初始化为空表
    for(int p=R[0].next; p; p=R[p].next)
    {
         j=R[p].keys[i];            //映射第i个关键字
        if(!front[j])
            front[j] = p;        //若front[j]为空,则把记录连接到front[j]的头指针上
        else
            R[end[j]].next = p;    //若front[j]的头指针已经连接过了,说明已j为关键字的数据已经有了,
                                //这时把上一个以j为关键字的数据指向当前的这个数,即下标为p的数据
        end[j] = p;        //尾指针重新指到每次更新的数据上
    }
}//distribute


void collect(SLCell *R, int i, ArrType front, ArrType end)
{
    //本算法按keys[i]自小到大地将f[0...RADIX-1]所指各子表依次链接成为一个链表
    for(int j=0; !front[j]; j++)
        ;                    //找到第一个不为空的子表
    R[0].next=front[j];            //重整静态链表
    int k=end[j];                    //k为当前子表的尾指针
    while(j<RADIX)
    {
        for(++j; j<RADIX; j++)
            if(front[j])        //找下一个非空子表
            {
                R[k].next=front[j];        //连接
                k=end[j];      
            }
    }
    R[k].next=0;                    //k指向最后一个非空子表的尾指针
}//collect




int main()
{
    SLList SLL;
    SLL=(SLList)malloc(MAX_SPACE*sizeof(Sllist));
    SLL->R=(SLCell *)malloc(MAX_SPACE*sizeof(SLCell));
    SLL->recnum=0;
    SLL->keynum=3;


    creatList(SLL);
    cout<<"排序前:"<<endl;
    print(SLL);


    ArrType front,end;
    for(int i = 1; i <= SLL->keynum; i++)    //按LSD法对各关键字进行分配和收集
    {
        distribute(SLL->R, i,front,end);    //第i趟分配
        collect(SLL->R, i,front,end);        //第i趟收集
        cout<<"第"<<i<<"分配和收集:"<<endl;
        print(SLL);
    }
    return 0;
}
0 0
原创粉丝点击