基础算法之四--排序:之基数排序

来源:互联网 发布:如何编程 编辑:程序博客网 时间:2024/04/29 01:55

本文 转载自网络, 偷个懒,因为原文程序很清晰 ,省的自己写了。

如果,作为转载, 与前面的构不成一个系列, 因此就当做翻译吧 -----其实是转载  呵呵, 望见谅

 

 

      基数排序是非比较排序算法,算法的时间复杂度是O(n)。

      基数排序的主要思路是,将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始, 依次进行一次稳定排序,这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

比如这样一个数列排序: 342 ,58, 576, 356, 以下描述演示了具体的排序过程(红色字体表示正在排序的数位)

第一次排序(个位):

3 4 2

5 7 6

3 5 6

0 5 8

第二次排序(十位):

4 2

5 6

5 8

7 6

第三次排序(百位):

0 5 8

3 4 2

3 5 6

5 7 6

结果: 58 342 356 576

下面通过两种方法对其进行了实现。

 

实现一:基于数组的基数排序算法

#include<iostream>using namespace std;#include <vector>int data[10]={73, 22, 93, 43, 55, 14, 28, 65, 39, 81};int tmp[10];int count[10];int maxbit(int data[],int n){    int d=1;    for(int i=0;i<n;i++)    {        int c=1;        int p=data[i];        while(p/10)        {            p=p/10;            c++;        }        if(c>d)            d=c;    }    return d;}void RadixSort(int data[],int n){        int d=maxbit(data,n);        int r=1;    for(int i=0;i<d;i++)    {            for(int i=0;i<10;i++)//装桶之前要先清桶            count[i]=0;        for(i=0;i<n;i++) //记录每个桶的记录数        {            int k=data[i]/r;            int q=k%10;            count[q]++;        }        for(i=1;i<10;i++)//计算位置        {            count[i]+=count[i-1];            //cout<<count[i]<<" ";        }        for(int j=n-1;j>=0;j--)        {            int p=data[j]/r;            int s=p%10;            tmp[count[s]-1]=data[j];            count[s]--;            //cout<<data[j]<<" ";        }        for(i=0;i<n;i++)        {            data[i]=tmp[i];            //cout<<tmp[i]<<" ";        }    //    cout<<endl;        r=r*10;    }}int main(){    cout<<"基数排序c++实现"<<endl;    //cout<<maxbit(data,10)<<endl;    cout<<"排序之前的数值:";    for(int i=0;i<10;i++)        cout<<data[i]<<" ";    cout<<endl;    RadixSort(data,10);    cout<<"排序之前的数值:";        for(i=0;i<10;i++)        cout<<data[i]<<" ";    cout<<endl;    return 0;}


实现二:基于静态链表基数排序算法实现

 

#include <iostream>using namespace std;int data[10]={73, 22, 93, 43, 55, 14, 28, 65, 39, 81};  //待排序的数组typedef struct list  //静态链表结构体类型{    int data;    int next;}List;List bucket[10];   //构造十个桶List d[10];        //将待排序数据构造成list类型的数组int maxbit(int data[],int n)   //计算待排序数组元数的最长的位数{    int d=1;    for(int i=0;i<n;i++)    {        int c=1;        int p=data[i];        while(p/10)        {            p=p/10;            c++;        }        if(c>d)            d=c;    }    return d;}void init(int data[],int n)  //清桶的过程,以及将临时的数组放到d【10】数组中{       int j=0;         for(j=0;j<n;j++)        {            bucket[j].next=-1;            bucket[j].data=j;        }        for(j=0;j<n;j++)        {          d[j].data=data[j];          d[j].next=-1;        }}void RadioSort(int data[],int n)   //基数排序的过程{        int p=maxbit(data,n);   //先求出最长的位数    int r=1;    for(int i=0;i<p;i++)   //执行装桶倒桶的次数    {        init(data,n);   //复位清桶的过程        if(i!=0)   //第一次装桶的时候从小到大开始装,之后都从大到小装桶        {                for(int k=n-1;k>=0;k--)            {                int a=d[k].data/r;                int b=a%10;                d[k].next=bucket[b].next;                bucket[b].next=k;            }        }        else        {            for(int k=0;k<n;k++)            {                int a=d[k].data/r;                int b=a%10;                d[k].next=bucket[b].next;                bucket[b].next=k;            }        }                int c=0;        for(int k=0;k<n;k++)   //倒桶的过程,将其放到data数组当中        {                            if(bucket[k].next!=-1)            {                int p=bucket[k].next;                data[c++]=d[p].data;                while(d[p].next!=-1){                        data[c++]=d[d[p].next].data;                        p=d[p].next;                }            }        }        r=r*10;  //为了后面对十位数以及高位求当前位置上的数字    }}int main(){    cout<<"基于静态链表的基数排序c++实现"<<endl;        //cout<<maxbit(data,10)<<endl;    cout<<"排序之前的数值:";    for(int i=0;i<10;i++)        cout<<data[i]<<" ";    cout<<endl;        RadioSort(data,10);    cout<<"排序之前的数值:";    for(i=0;i<10;i++)        cout<<data[i]<<" ";    return 0;}


 

 

转载自:http://www.cnblogs.com/dlutxm/archive/2011/10/20/2219321.html

 

原创粉丝点击