当前位置:编程学习 > 网站相关 >>

基数排序之LSD篇 (知识点小结)

基数排序(radix sort)是属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O ( d(n+radix ) ),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法(比较性排序法的时间复杂度下限是O(n log n))。
 
 
 
 
 
基本思路(载自百科):
 
解法 
  基数排序的方式可以采用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相反,是由高位数为基底开始进行分配,其他的演算方式则都相同。 
 
 
 
 
 
代码示例:
 
 
 
 
[cpp] view plaincopyprint?#include<iostream>   
  
using namespace std;  
  
const int MAXSIZE=10;  
  
int main(){  
    int data[MAXSIZE]={43,12,54,23,14,65,21,90,33,86};//先初始化数组   
    int tmp_queue[MAXSIZE][MAXSIZE]={0};  
    int order[MAXSIZE]={0};  
  
    int i;  
  
    cout<<"排序前数组顺序为:"<<endl;  
      
    for(i=0;i<MAXSIZE-1;i++)//输出原始的数组   
        cout<<data[i]<<" ";  
    cout<<data[i]<<endl;  
  
    int n=1,k;  
    int lsd,flag=1;  
  
    while( n <= MAXSIZE){  
        for(i=0 ;i<MAXSIZE;i++){//按照排序码的大小,将数据分配到不同的队列中   
            lsd=((data[i]/n)%10);  
            tmp_queue[lsd][order[lsd]++]=data[i];  
        }  
  
        n*=10;//选择的排序码向高位移动一位   
        k=0;  
        int j;  
  
        cout<<"\n第"<<flag++<<"趟分配和收集后的数据顺序为:"<<endl;  
        for( i=0;i<MAXSIZE;i++){  
                if( order[i] != 0){  
                    for( j=0;j<order[i];j++){  
                        data[k]=tmp_queue[i][j];  
                        cout<<data[k++]<<" ";  
                    }  
                }  
                order[i]=0;//重新将数组长度标记为0 以便下一次循环时候使用   
        }  
    }  
  
    cout<<"\n\nLSD基数排序法结束后的数据顺序为:"<<endl;  
    for(i=0;i<MAXSIZE-1;i++)  
        cout<<data[i]<<" ";  
    cout<<data[i]<<endl;//输出最后一个数据   
    return 0;  
}  
 
#include<iostream>
 
using namespace std;
 
const int MAXSIZE=10;
 
int main(){
int data[MAXSIZE]={43,12,54,23,14,65,21,90,33,86};//先初始化数组
int tmp_queue[MAXSIZE][MAXSIZE]={0};
int order[MAXSIZE]={0};
 
int i;
 
cout<<"排序前数组顺序为:"<<endl;
 
for(i=0;i<MAXSIZE-1;i++)//输出原始的数组
cout<<data[i]<<" ";
cout<<data[i]<<endl;
 
int n=1,k;
int lsd,flag=1;
 
while( n <= MAXSIZE){
for(i=0 ;i<MAXSIZE;i++){//按照排序码的大小,将数据分配到不同的队列中
lsd=((data[i]/n)%10);
tmp_queue[lsd][order[lsd]++]=data[i];
}
 
n*=10;//选择的排序码向高位移动一位
k=0;
int j;
 
cout<<"\n第"<<flag++<<"趟分配和收集后的数据顺序为:"<<endl;
for( i=0;i<MAXSIZE;i++){
if( order[i] != 0){
for( j=0;j<order[i];j++){
data[k]=tmp_queue[i][j];
cout<<data[k++]<<" ";
}
}
order[i]=0;//重新将数组长度标记为0 以便下一次循环时候使用
}
}
 
cout<<"\n\nLSD基数排序法结束后的数据顺序为:"<<endl;
for(i=0;i<MAXSIZE-1;i++)
cout<<data[i]<<" ";
cout<<data[i]<<endl;//输出最后一个数据
return 0;
}
 
运行结果:
\
 
基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
  基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
 
 
时间效率:设待排序列为n
补充:综合编程 , 其他综合 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,