链式基数排序

在这里插入图片描述
将一个关键字,如278,分为三个关键字‘2’,‘7’,‘8’。
把待排元素按某一位从低到高添加到相应的f-e中,其实f和e只是指向头尾两个元素,链表的连接关系实际上是通过修改r的next指针实现的。

//
// Created by dgm on 19-4-23.
//
#include <iostream>
#define MaxNum 10000
#define Radix 10
using namespace std;
typedef int KeyType;
typedef char* Info;
typedef int ArrType[Radix];

typedef struct {
    KeyType key;    //单个关键字
    Info info;
    int next;
}SLCell;

typedef struct {
    SLCell r[MaxNum];
    int recnum; //待排元素数目
    int keynum; //多关键字个数
}SLList;        //静态链表

KeyType ord(KeyType k,int i)    //取关键字的第i位(将单关键字拆分为多关键字)
{
    for (int j = 1; j < i; ++j) k/=10;
    return k%10;
}

void Distribute(SLList&L,int i,ArrType&front,ArrType&rear)//按照第i位将每个元素分配到
                                                          // 相应的链表中
{
    for (int i = 0; i < Radix; ++i) front[i]=0; //初始化
    for (auto p = L.r[0].next; p ; p=L.r[p].next) {//p是下标
        auto j=ord(L.r[p].key,i);   //取得元素的第i位
        if (!front[j]) front[j]=p;  //如果相应链表为空,加入
        else
            L.r[rear[j]].next=p;    //对照以上图片,实现每一列的链接
        //注意f-e并不是链表,而只是首尾元素的下标,真正的链表是在r中通过next实现的
        rear[j]=p;  //更改链表的尾为新加入元素的下标
    }
}

void Collect(SLList&L,ArrType front,ArrType rear)
{
    int j;
    for (j = 0; !front[j] ; ++j);//第一个非空的列
    L.r[0].next=front[j];   //按从左到右的顺序加入到r中
    auto t=rear[j]; //当前列的尾,让他通过next指向下一列的头
    for (j ; j < Radix; ++j) {
        for (j ; !front[j] && j<Radix-1; ++j);  //下一个非空列
        if (front[j]){
            L.r[t].next=front[j];//上一列的尾与这一列的头连起来
            t=rear[j];
        }
    }
    L.r[t].next=0;  //最后一个元素指向0,标识结束
}

void RadixSort(SLList&L)
{
    ArrType front,rear;
    for (int i = 0; i < L.recnum; ++i) L.r[i].next=i+1;//建立静态链表
    L.r[L.recnum].next=0;
    for (int i = 1; i <= L.keynum; ++i) {
        Distribute(L,i,front,rear);
        Collect(L,front,rear);
    }
}

int main()
{
    SLList L;
    L.recnum=10;    
    L.keynum=3;
    for (int i = 1; i <= L.recnum; ++i) L.r[i].key=rand()%1000;
    RadixSort(L);
    for (int p = L.r[0].next; p ; p=L.r[p].next) cout<<L.r[p].key<<" ";
    cout<<endl;
    return 0;
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值