基数排序
来源:互联网 发布:foxmail邮件数据位置 编辑:程序博客网 时间:2024/04/30 06:36
今天偶尔看来论坛上,有人写了个基数排序的程序,就帮着给那哥们修改,顺便复习一下基数排序,下面是那个哥们的代码,对了是修改过的 。百度搜索得到基数排序的概念:
源之:
http://baike.baidu.com/view/1170573.htm
基数排序
解法
基数排序的方式可以采用LSD(Least sgnificant digital)或MSD(Most sgnificant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
以LSD为例,假设原来有一串数值如下所示:
73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
14, 22, 28, 39, 43, 55, 65, 73, 81, 93
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好,MSD的方式恰与LSD相反,是由高位数为基底开始进行分配,其他的演算方式则都相同。
源之:http://topic.csdn.net/u/20090121/10/1e8431e9-458a-47b7-b20b-00e55fa87aa0.html?seed=1178430914
#include<iostream.h>
#include<stdlib.h>
const int MaxQSize=50;
typedef int DataType;
enum DigitKind{ones,tens};
class Queue
{
private:
int front,rear,count;
DataType qlist[MaxQSize];
public:
Queue();
void QInsert(const DataType& item);
DataType QDelete();
void ClearQueue();
DataType QFront()const;
int QLength()const;
int QEmpty()const;
int QFull()const;
};
Queue::Queue():front(0),rear(0),count(0){};
void Queue::QInsert(const DataType& item)
{
if(count==MaxQSize)
{
cout<<"Queue overflow!"<<endl;
exit(1);
}
qlist[rear]=item;
rear=(rear+1)%MaxQSize;
++count;
}
DataType Queue::QDelete()
{
DataType temp;
if(count==0)
{
cout<<"Deleting element from an empty queue!"<<endl;
exit(1);
}
temp=qlist[front];
front=(front+1)%MaxQSize;
--count;
return temp;
}
void Queue::ClearQueue()
{
count=0;
front=0;
rear=0;
}
DataType Queue::QFront()const
{
return qlist[front];
}
int Queue::QLength()const
{
return count;
}
int Queue::QEmpty()const
{
if(count==0)
return 1;
else
return 0;
}
int Queue::QFull()const
{
if(count==MaxQSize)
return 1;
else
return 0;
}
void Distribute(int L[],Queue digitQueue[],int n,DigitKind kind)
{
int i;
for(i=0;i<n;i++)
if(kind==ones)
digitQueue[L[i]%10].QInsert(L[i]);
else
digitQueue[L[i]/10].QInsert(L[i]);
}
void Collect(Queue digitQueue[],int L[])
{
int i=0,digit=0;
for(digit=0;digit<10;digit++)
{
while(digitQueue[digit].QEmpty()==0)
{
L[i++]=digitQueue[digit].QDelete();
}
}
}
int main()
{
Queue digitQueue[10]; //存放数据的十个队列
int L[50];
int i=0;
for(i=0;i<50;i++)
{
srand(i);
L[i]=rand()%100;
}
for(i=0;i<50;i++)
{
cout<<L[i]<<' ';
}
cout<<endl<<endl;
Distribute(L,digitQueue,50,ones);
Collect(digitQueue,L);
for(i=0;i<50;i++)
{
cout<<L[i]<<' ';
}
cout<<endl<<endl;
Distribute(L,digitQueue,50,tens);
Collect(digitQueue,L);
for(i=0;i<50;i++)
{
cout<<L[i]<<' ';
}
return 0;
}
后来自己又重新写了一个:
#include<iostream>
#include<stdlib.h>
#include <ctime>
using namespace std;
const int MaxQSize=50;
typedef int DataType;
enum DigitKind{ones,tens,huands};
inline int pow10(int n)
{
int res = 1;
while (--n >= 0)
res *= 10;
return res;
}
class Queue
{
private:
int front,rear,count;
DataType qlist[MaxQSize];
public:
Queue();
void QInsert(const DataType& item);
DataType QDelete();
void ClearQueue();
DataType QFront()const;
int QLength()const;
int QEmpty()const;
int QFull()const;
};
Queue::Queue():front(0),rear(0),count(0){};
void Queue::QInsert(const DataType& item)
{
if(count==MaxQSize)
{
cout<<"Queue overflow!"<<endl;
exit(1);
}
qlist[rear]=item;
rear=(rear+1)%MaxQSize;
++count;
}
DataType Queue::QDelete()
{
DataType temp;
if(count==0)
{
cout<<"Deleting element from an empty queue!"<<endl;
exit(1);
}
temp=qlist[front];
front=(front+1)%MaxQSize;
--count;
return temp;
}
void Queue::ClearQueue()
{
count=0;
front=0;
rear=0;
}
DataType Queue::QFront()const
{
return qlist[front];
}
int Queue::QLength()const
{
return count;
}
int Queue::QEmpty()const
{
if(count==0)
return 1;
else
return 0;
}
int Queue::QFull()const
{
if(count==MaxQSize)
return 1;
else
return 0;
}
void Distribute(int L[],Queue digitQueue[],int n,DigitKind kind)
{
int i;
for(i=0;i<n;i++)
{
switch( kind )
{
case ones:
digitQueue[L[i]%10].QInsert(L[i]);
break;
case tens:
digitQueue[(L[i]/10)%10].QInsert(L[i]);
break;
case huands:
digitQueue[L[i]/100].QInsert(L[i]);
break;
default:
cout<<"Too high digits to sequence"<<endl;
}
}
}
void Collect(Queue digitQueue[],int L[])
{
int i=0,digit=0;
for(digit=0;digit<10;digit++)
{
while(digitQueue[digit].QEmpty()==0)
{
L[i++]=digitQueue[digit].QDelete();
}
}
}
void JiShuSeq(int L[],Queue digitQueue[],int n,int digits)
{
DigitKind kind;
for(int i=0; i<=digits-1;i++)
{
switch (i)
{
case 0:
kind = ones;
break;
case 1:
kind = tens;
break;
case 2:
kind = huands;
break;
}
Distribute(L,digitQueue,n,kind);
Collect(digitQueue,L);
}
}
int main()
{
Queue digitQueue[10]; //there are ten data in this queue(队列)
int L[50];
int i=0;
unsigned short digits = 0;
cout<<"How many digits sequence do you want ?"<<endl;
cout<<"I want :";
cin>>digits;
cout<<endl;
unsigned short const domain = pow10(digits);
srand((unsigned int)time(NULL));
for(int i=0;i<50;i++)
{
L[i]=rand()%(1000);
}
for(int i=0;i<50;i++)
{
cout<<L[i]<<' ';
}
cout<<endl<<"The result after the JiShu sequence:"<<endl;
JiShuSeq(L,digitQueue,50,digits);
for(int i=0;i<50;i++)
{
cout<<L[i]<<' ';
}
//getchar();
cin.get();
return 0;
}
srand((unsigned int)time(NULL));的位置以前放在下面for循环里面,后来发现每次都是相同的数据,后来将其放到for循环外面后,发现成功了.以后要警戒.