您的位置:首页 > 理论基础 > 数据结构算法

C++代码,数据结构-内部排序-基数排序-链式基数排序

2014-03-19 17:59 423 查看
基数排序是一种从记录最次位关键字开始排序的方法,比如数据,从个位开始排序,具体的方法可以参照书上,我把书上的伪代码以可运行代码的形式呈现:

难点:书上 f e 数组的实现用了链表,节省了辅助空间,f数组的值只指向该位数第一个值在序列中的位置,该位数上的序列依靠记录本身带有的next指针来连接,e数组的值只指向该位数序列上最后一个值在序列上的位置。

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<cstdlib>
#include<ctime>
using namespace std;

#define Max_num_of_key 8
#define Radix 10
#define Max_space 51000
struct Slcell{
int keys[Max_num_of_key];
int data;
int next;
};

struct Slist{
Slcell r[Max_space];
int keymax;
int length;
};
typedef int Arrtype[Radix];

void buildslist(Slist &sl){//与前面不同,这里的记录多个一个keys用于记录每个data每一位上的数字,用于排序
cout<<"输入需要排序的数据数目和数据的最大位数"<<endl;
cin>>sl.length>>sl.keymax;
cout<<"依次输入数据"<<endl;
for(int i=1;i<=sl.length;++i){
    int x;
    cin>>x;
    sl.r[i].data=x;
}
for(int i=1;i<=sl.length;++i){//将每一位存储起来,低位对应低位
    int x=sl.r[i].data;
    for(int j=1;j<=sl.keymax;++j){
        sl.r[i].keys[j]=x%10;
        x/=10;
    }
}
}

void Distribute(Slcell r[],int i,Arrtype &f,Arrtype&e){//按i位上的关键字分配
for(int j=0;j<Radix;++j)f[j]=0;//初始化f数组
for(int p=r[0].next;p;p=r[p].next){//从第一个记录开始
    int j=r[p].keys[i];//用j记录次记录i位上的关键字
    if(!f[j])f[j]=p;//f数组的j位上为0,则此数是第一个
    else r[e[j]].next=p;//不然 此数排在f数组j位最后一个数后面
e[j]=p;//e数组j位重新赋值
    }
}

void Collect(Slcell r[],int i,Arrtype &f,Arrtype&e){//对按i位关键字分配完的各子表进行收集,
 int j;
 for(j=0;!f[j];++j);//寻找第一个非空的子表
   r[0].next=f[j]; int t=e[j];//头结点指向第一个结点
while(j<Radix-1){//不断寻找下一个非空子表
   ++j;
    if(f[j]) {r[t].next=f[j];t=e[j];}//连接两个子表
}
r[t].next=0;//最后一个结点指向0

}

void Radixsort(Slist &L){//链表基数排序
    Arrtype f,e;
for(int i=0;i<L.length;++i) L.r[i].next=i+1;//先改造成静态链表
L.r[L.length].next=0;//最后一个位指向0,用于判定
for(int i=1;i<=L.keymax;++i){//序列中数字最大的位数为多少,则需要排序几次
    Distribute(L.r,i,f,e);//按i位上的关键字分配,
Collect(L.r,i,f,e);//对已按i位上一分配了的进行收集
}

}

int main(){

Slist sl;
buildslist(sl);//建立记录表

Radixsort(sl);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: