算法就是这么一回事(排序)(第五部分)
八、基数排序
它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
基数排序的时间复杂度是 O(k·n),其中n是排序元素个数,k是数字位数。注意这不是说这个时间复杂度一定优于O(n·log(n)),k的大小取决于数字位的选择(比如比特位数),和待排序数据所属数据类型的全集的大小;k决定了进行多少轮处理,而n是每轮处理的操作数目。
以排序n个不同整数来举例,假定这些整数以B为底,这样每位数都有B个不同的数字,k = logB(N),N是待排序数据类型全集的势。虽然有B个不同的数字,需要B个不同的桶,但在每一轮处理中,判断每个待排序数据项只需要一次计算确定对应数位的值,因此在每一轮处理的时候都需要平均n 次操作来把整数放到合适的桶中去,所以就有:
- k 约等于 logB(N)
所以,基数排序的平均时间T就是:
- T ~= logB(N)·n
其中前一项是一个与输入数据无关的常数,当然该项不一定小于logn
如果考虑和边角排序进行对照,基数排序的形式复杂度虽然不一定更小,但由于不进行比较,因此其基本操作的代价较小,而且在适当选择的B之下,k一般不大于logn,所以基数排序一般要快过基于比较的排序,比如快速排序。(转自维基百科基数排序)
1 #include <iostream> 2 #include <iterator> 3 #include <vector> 4 #include <ctime> 5 #include <random> 6 #include <functional> 7 #include <algorithm> 8 using namespace std; 9 int intSwap(int& a,int& b) 10 { 11 int intswaptemp=a; 12 a=b; 13 b=intswaptemp; 14 return 0; 15 } 16 /*------------------------------------------- 17 -----------------基数排序---------------------- 18 ---------------------------------------------*/ 19 int getbytefun(vector<int>& ivec)//获得位数 20 { 21 int p10=10; 22 int bit=1;//保存最大位数 23 for(auto p:ivec) 24 { 25 while(p>=p10)//10也是两位数 26 { 27 p10*=10; 28 ++bit; 29 } 30 } 31 return bit; 32 } 33 int RadixSort(vector<int> &ivec) 34 { 35 int maxbit=getbytefun(ivec); 36 int *ivectemp=new int[ivec.size()];//temp 37 int *count=new int[10];//计数器,统计(0,1,2,3,4,5,6,7,8,9)出现的次数 38 int i,j,k; 39 int radix=1; 40 for(i=1;i<=maxbit;i++)//进行maxbit次排序,因为有maxbit位需要处理 41 { 42 for(int j=0;j<10;j++) 43 count[j]=0;//清空count,并设定初始值为0 44 for(auto &p:ivec) 45 { 46 k=((p)/radix)%10; 47 count[k]++;//统计数据相同一位(例如都是第三位)某个数字出现的次数 48 } 49 50 //-------------------------------------------------------------------------- 51 for(j=1;j<10;j++) 52 count[j]=count[j-1]+count[j];//通过该算法处理使得每一位最小数字以上都至少为1,为后面左准备 53 //这一句也就是基数排序的核心了, 54 //------------------------------------------------------------------------- 55 for(j=ivec.size()-1;j>=0;j--) 56 { 57 k=(ivec[j]/radix)%10;//某一位字符 58 ivectemp[count[k]-1]=ivec[j];//按照各位上面定义来实现排序某一位功能 59 count[k]--; 60 } 61 for(j=0;j<ivec.size();j++) 62 ivec[j]=ivectemp[j]; 63 radix*=10; 64 } 65 delete []ivectemp; 66 delete []count; 67 return 0; 68 } 69 int main() 70 { 71 clock_t start,end; 72 vector<int> ivec,copyivec; 73 srand(14); 74 for(int i=0;i<10000;i++)//10k 75 ivec.push_back((int)rand()); 76 copyivec=ivec; 77 start=clock(); 78 RadixSort(ivec); 79 end=clock(); 80 for(int i=0;i<10000;i+=500) 81 cout<<ivec[i]<<'\t'; 82 cout<<endl; 83 cout<<"the time of 1 is "<<end-start<<endl; 84 85 return 0; 86 }
详情请参考http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html