基数排序c++实现
基数排序是非比较排序算法,算法的时间复杂度是O(n)。
基数排序的主要思路是,将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始, 依次进行一次稳定排序,这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
比如这样一个数列排序: 342 ,58, 576, 356, 以下描述演示了具体的排序过程(红色字体表示正在排序的数位) http://www.cnblogs.com/sun/archive/2008/06/26/1230095.html
第一次排序(个位):
3 4 2
5 7 6
3 5 6
0 5 8
第二次排序(十位):
3 4 2
3 5 6
0 5 8
5 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;
}
运行结果如下:
基于静态链表的基数排序c++实现
排序之前的数值:73 22 93 43 55 14 28 65 39 81
排序之前的数值:14 22 28 39 43 55 65 73 81 93