基数排序算法测试及性能分析

原创 2007年09月14日 11:03:00
 基数排序算法复杂度为O(n),在所有排序算法中是最快的,但并不是所有情况都能使用。
使用基数排序的一个很重要的思想是:把关键字拆分为多个字关键字,然后依次按子关键字排序。
有两种方式,主优先(0号-->(n-1)号),最次优先((n-1)号-->0号)
从目标对于整数排序来看,后者比较方便,
如果使用前者的话,对0号子关键字排序后还需要记录不同的子序列,每进行一次子关键字排序必定会产生一系列的字序列,结合BFS思想来理解比较容易。

开始的时候就说了,并不是所有的情况都能使用基数排序,例如当关键字比较复杂,无法合理有效地拆分为多关键字的时候。

下面这段即为基数排序的测试程序,测试对象510300个随机整数
[1]  BaseDigitSort                以十进制方式对整数进行基数排序,时间   844 ms
[2]  BaseDigitSort_hex       以16进制方式对整数进行基数排序,时间   109 ms
[3]  Qsort                               快速排序,调用qsort,用于比较,   时间   718 ms


109 * log(l09) = 737 约等于 [3]的718,与理论上的时间相吻合
如果采用[1]方式,其与[2]的区别并不在于算法本身,而是[1]中求整数每一位数字的时候需要进行除法和求余操作,大大降低效率,而[2]只需要进行逻辑运算即可。

#include <fstream>
#include 
<iostream>
#include 
<windows.h>
using namespace std ;

#include 
<stdlib.h>
#include 
<time.h>

#define MAX_VALUE_NUM 1000005

int level_hex[8= 0481216202428 } ;
int level[11= 01101001000100001000001000000100000001000000001000000000 } ;
int value[MAX_VALUE_NUM], temp[MAX_VALUE_NUM] ;        // 暂时只考虑正整数


inline 
int GetSpecDigitalInValue ( int value, int index )
{
    value 
/= level[index+1] ;
    
return ( value % 10 ) ;
}


void BaseDigitalSort ( int* pValue, int num, bool type=true )
{
    
int i, j, digit, count[10] ;
    
for ( i = 0; ; i++ )
    
{
        memset ( count, 
0sizeof(count) ) ;

        
for ( j = 0; j < num; j++ )
            count[GetSpecDigitalInValue(pValue[j],i)]
++ ;

        
if ( count[0== num )
            
break ;

        
for ( j = 1; j < 10; j++ )
            count[j] 
+= count[j-1] ;

        
for ( j = num-1; j >= 0; j-- )
        
{
            digit 
= GetSpecDigitalInValue(pValue[j],i) ;
            temp[count[digit]
-1= pValue[j] ;
            count[digit] 
-- ;

        }


        memcpy ( pValue, temp, 
sizeof(int)*num ) ;
    }

}


void BaseDigitalSort_hex ( int* pValue, int num, bool type=true )
{
    
int i, j, digit, count_hex[16] ;
    
for ( i = 0; i < 8; i++ )
    
{
        memset ( count_hex, 
0sizeof(count_hex) ) ;

        
for ( j = 0; j < num; j++ )
            count_hex[( ( value[j] 
>> level_hex[i] ) & 0xF )]++ ;

        
if ( count_hex[0== num )
            
break ;

        
for ( j = 1; j < 16; j++ )
            count_hex[j] 
+= count_hex[j-1] ;

        
for ( j = num-1; j >= 0; j-- )
        
{
            digit 
= ( ( value[j] >> level_hex[i] ) & 0xF ) ;
            temp[count_hex[digit]
-1= pValue[j] ;
            count_hex[digit] 
-- ;

        }


        memcpy ( pValue, temp, 
sizeof(int)*num ) ;
    }

}


void UseBaseDigitSort ()
{
    ifstream fin ( 
"value2.in" ) ;
    ofstream fout ( 
"BaseDigitSort.out" ) ;

    
int count = 0 ;
    
while ( fin >> value[count] ) 
        count
++ ;

    
int beg = clock () ;
    BaseDigitalSort ( value, count ) ;
    
int end = clock () ;
    cout 
<< "BaseDigitSort ( " << count << " )" << ' ' << end - beg << endl ;


    
for ( int i = 0; i < count; i++ )
        fout 
<< value[i] << endl ;

    fin.close () ;
    fout.close () ;
}


void UseBaseDigitSort_hex ()
{
    ifstream fin ( 
"value2.in" ) ;
    ofstream fout ( 
"BaseDigitSort.out" ) ;

    
int count = 0 ;
    
while ( fin >> value[count] ) 
        count
++ ;

    
int beg = clock () ;
    BaseDigitalSort_hex ( value, count ) ;
    
int end = clock () ;
    cout 
<< "BaseDigitSort_hex ( " << count << " )" << ' ' << end - beg << endl ;


    
for ( int i = 0; i < count; i++ )
        fout 
<< value[i] << endl ;

    fin.close () ;
    fout.close () ;
}


int cmp ( const void* a, const void* b )
{
    
return *((int*)a) - *((int*)b ) ;
}


void UseQsort ()
{
    ifstream fin ( 
"value2.in" ) ;
    ofstream fout ( 
"Qsort.out" ) ;

    
int count = 0 ;
    
while ( fin >> value[count] ) 
        count
++ ;

    
int beg = clock () ;
    qsort ( value, count, 
sizeof(int), cmp ) ;
    
int end = clock () ;
    cout 
<< "Qsort ( " << count << " )" << ' ' << end - beg << endl ;


    
for ( int i = 0; i < count; i++ )
        fout 
<< value[i] << endl ;

    fin.close () ;
    fout.close () ;
}


int _tmain(int argc, _TCHAR* argv[])
{
        
// 十进制方式的基数排序
    UseBaseDigitSort () ;
       
        
// 16进制方式的基数排序
    UseBaseDigitSort_hex () ;

        
// 调用qsort排序,用于比较
    UseQsort () ;

    
return 0;
}


/*
BaseDigitSort ( 510300 )        844
BaseDigitSort_hex ( 510300 )    109
Qsort ( 510300 )        718
*/
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

基数排序算法 java实现

  • 2012-02-20 15:54
  • 32KB
  • 下载

基数排序算法

  • 2014-08-16 11:17
  • 736B
  • 下载

基数排序算法分析

基数排序:主要思想是把数字按位进行比较,从个位,十位... 到最高位,取得每个位的单个数字逐一进行比较和移动。 由于整数也可以用字符串表达(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能...

常见排序算法汇总与分析(下)(基数排序与计数排序)

本篇汇总的算法将不再是基于比较的排序算法,因此会突破这类算法的时间复杂度下界O(nlog2n)。如果有朋友对前面的内容感兴趣,可以先去看看常见排序算法汇总与分析(中)(选择排序与归并排序) 我们先来...

基数排序算法

线性排序算法(计数排序,基数排序,桶排序)分析及实现

写在前面 大家都知道的是,基于比较的排序算法的时间复杂度的下界是 O(n log(n))。这一结论是可以证明的,所以在基于比较的算法中是找不到时间复杂度为 O(n)的算法的。这时候,非基于比较的算法...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)