线性时间排序算法

基于比较的算法的时间下限为NlogN,而计数排序、桶排序和基数排序这几种非比较算法却可以突破这个下限,仅管它们对输入都有一定限制条件,即输入数据必须在某个范围内。但是,这些算法还是非常实用的。闲着没事,写了一下(详细见《算法导论》):

ExpandedBlockStart.gif 代码
#define  NO_CMP_SORT
#ifdef NO_CMP_SORT

#define   N    10
#define   BUCKET_SIZE    10

#define   RADIX_SORT

#ifdef COUNT_SORT
int  count_sort( int *  A,  int *  B,  int  n,  int  k)
{
    
int  i;
    
    
int *   C  =  ( int * )malloc((k + 1 ) * sizeof ( int ));
    
if (C  ==  NULL)
        
return   - 1 ;
    
    memset(C, 
0  , (k + 1 ) * sizeof ( int ));
    
    
for  (i  =   1 ; i  <=  n; i ++ )
        C[A[i]]
++ ;
    
    
for (i  =   1 ; i  <=  k; i ++ )
        C[i] 
+=  C[i - 1 ];
    
for  (i  =  n; i  >=   1 ; i -- )
    {
        B[C[A[i]]] 
=  A[i];
        C[A[i]]
-- ;
    }
    free(C);
    
return   0 ;
}
#endif


#ifdef  BUCKET_SORT

typedef 
struct   node
{
    
int     data;
    
struct  node *  next;
}node;

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

// 桶排序
void  bucketsort( int *  A,  int  n,  int  k)
{
    node
*     bucket[BUCKET_SIZE + 1 ];
    node
*     p;
    node
*    pre;
    
int  i, start, end, idx;

    memset(bucket, 
0 sizeof (bucket));
    
for  (i  =   1 ; i  <=  n; i ++ )
    {
        idx 
=  A[i] * BUCKET_SIZE / k;
        p 
=  bucket[idx];
        bucket[idx] 
=  (node * )malloc( sizeof (node));
        bucket[idx]
-> data  =  A[i];
        bucket[idx]
-> next  =  p;
    }

    end 
=   1 ;
    
for  (i  =   0 ; i  <=  BUCKET_SIZE; i ++ )
    {
        start 
=  end;
        
for (p  =  bucket[i]; p;)
        {
            A[end
++ =  p -> data;
            pre 
=  p;
            p 
=  p -> next;
            free(pre);
        }
        qsort(A
+ start, end - start,  sizeof (A[ 0 ]), cmp);
    }
}

#endif

#ifdef RADIX_SORT
#define   N_FIELD    2
typedef 
struct  user_data
{
    
int  fields[N_FIELD];
}user_data;

typedef 
struct  node
{
    user_data  data;
    
struct  node *  next;
}node;

void  bucketsort(user_data *     A,  int  n,  int  k,  int  fld_id)
{
    node
*     bucket[BUCKET_SIZE + 1 ];
    node
*     p;
    node
*     pre;
    
int         i, j, off, idx;

    memset(bucket, 
0 sizeof (bucket));
    
for  (i  =   1 ; i  <=  n; i ++ )
    {
        idx 
=  A[i].fields[fld_id]  *  BUCKET_SIZE  /  k;
        p 
=  bucket[idx];
        bucket[idx] 
=  (node * ) malloc( sizeof (node));
        bucket[idx]
-> data  =  A[i];
        bucket[idx]
-> next  =  p;
    }

    
for (i  =  j  =   0 ; i  <=  BUCKET_SIZE; i ++ )
    {
        
for (p  =  bucket[i]; p; p  =  p -> next)
            j
++ ;
        
for (p  =  bucket[i], off  =   1 ; p; off ++ )
        {
            A[j
- off + 1 =  p -> data;
            pre 
=  p;
            p 
=  p -> next;
            free(pre);
        }
    }    
}
// 基数排序
void  radixsort(user_data *  A,  int  n,  int  k)
{
    
int  i;
    
for (i  =  N_FIELD - 1 ; i  >=   0 ; i -- )
        bucketsort(A, n, k, i);
}
#endif   // RADIX_SORT

#endif   // NO_CMP_SORT


int  main()
{
#ifdef NO_CMP_SORT
#ifdef COUNT_SORT

    
// 计数排序
     int  i, a[N + 1 ], b[N + 1 ], k  =   10 ;
    
    
for  (i  =   1 ; i  <=  N; i ++ )
        a[i] 
=  rand() % +   1 ;
    printf(
" before count sort:\n " );
    
for (i  =   1 ; i  <=  N; i ++ )
        printf(
" %d  " , a[i]);
        
    count_sort(a, b, N, k);
    printf(
" \nafter count sort:\n " );
    
for (i  =   1 ; i  <=  N; i ++ )
        printf(
" %d  " , b[i]);

#endif   // COUNT_SORT

#ifdef BUCKET_SORT
    
int  i, a[N + 1 ], b[N + 1 ], k  =   10 ;
    
    
for  (i  =   1 ; i  <=  N; i ++ )
        a[i] 
=  rand() % +   1 ;
    printf(
" before bucket sort:\n " );
    
for (i  =   1 ; i  <=  N; i ++ )
        printf(
" %d  " , a[i]);
    
    bucketsort(a, N, k);
    printf(
" \nafter bucket sort:\n " );
    
for (i  =   1 ; i  <=  N; i ++ )
        printf(
" %d  " , a[i]);
#endif   // BUCKET_SORT

#ifdef RADIX_SORT
    
int  i, j, k  =   10 ;
    user_data a[N
+ 1 ];
    
    
for  (i  =   1 ; i  <=  N; i ++ )
    {
        
for (j  =   0 ; j  <  N_FIELD; j ++ )
            a[i].fields[j] 
=  rand() % +   1 ;
    }
    printf(
" before radix sort:\n " );
    
for (i  =   1 ; i  <=  N; i ++ )
    {
        printf(
" ( " );
        
for (j  =   0 ; j  <  N_FIELD; j ++ )
            printf(
" %d  " , a[i].fields[j]);
        printf(
" " );
    }
    
    radixsort(a, N, k);
    printf(
" \nafter radix sort:\n " );
    
for (i  =   1 ; i  <=  N; i ++ )
    {
        printf(
" ( " );
        
for (j  =   0 ; j  <  N_FIELD; j ++ )
            printf(
" %d  " , a[i].fields[j]);
        printf(
" " );
    }
#endif   //  RADIX_SORT

#endif   //  NO_CMP_SORT
    
return   0 ;
}

 

 


作者:arrowcat
出处:http://www.cnblogs.com/hustcat/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值