线性时间排序算法

基于比较的算法的时间下限为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, 
0sizeof(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, 
0sizeof(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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

posted @ 2010-05-20 20:30  YY哥  阅读(1939)  评论(0编辑  收藏  举报