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


#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() % k + 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() % k + 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() % k + 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 ;
}
#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() % k + 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() % k + 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() % k + 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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。