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