关闭

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

1423人阅读 评论(3) 收藏 举报
 基数排序算法复杂度为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
*/
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:32546次
    • 积分:468
    • 等级:
    • 排名:千里之外
    • 原创:12篇
    • 转载:0篇
    • 译文:0篇
    • 评论:19条
    最新评论