[算法导论读书笔记]线性时间排序——计数排序

来源:互联网 发布:数据库 公开课评课 编辑:程序博客网 时间:2024/06/05 07:32

计数排序的要求:

    计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数。当 k = O(n)时,计数器的排序运行时间为O(n)。

基本思想:

    计数器排序的基本思想就是堆每一个输入元素x,确定出小于x的元素个数。有了这一信息就可以把x直接放在它在最终输出数组中的位置上。例如,如果有17个元素小于x,则x就属于第18个输出位置。当有几个元素相同时,这个方案要稍做修改,因为不能把它们放在同一输出位置上。

设计:

    在计数排序的代码中,我们假定输入是数组A[1……n],length[A] = n。另外,还需要两个数组:存放排序结果的B[1……n],以及提高哦功能临时存储区的C[0……k]。

伪代码:


实现&&测试:

#include <stdio.h>#include <time.h>#include <algorithm>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <sys/times.h>#define MAX 1000000#define DEBUGvoid Count_Sort( int *A, int *B, int *C){int i = 0;int j = 0;for( j = 0; j < MAX; j++){C[ A[j] ]++;}for( i = 1; i < 100; i++){C[i] += C[i- 1];}for( j = MAX - 1; j >= 0; j--){B[ C[ A[j] ] - 1]= A[j];C[ A[j]]--;}}int main(int argc, char* argv[]){int clock_per_sec = sysconf(_SC_CLK_TCK);long beg, end;struct tms begTms, endTms;int A[MAX];int B[MAX];int C[100];int i;//produce data srand(time(0));for(  i = 0; i < MAX; i++ ){A[i] = rand() % 100;} memset(C, 0, sizeof(int) * 100);beg = times(&begTms);Count_Sort(A, B, C);end = times(&endTms);printf("The time of count sort is:%ld ms\n", (end - beg) * 1000 / clock_per_sec);beg = times(&begTms);std::sort(A, A + MAX);end = times(&endTms);printf("The time of sort function in labrary is:%ld ms\n", (end - beg) * 1000 / clock_per_sec);#ifdef DEBUGprintf("result of count sort:\n");for( i =11100; i < 1000000; i+=2000){printf("%d\t", B[i]);}printf("\n");printf("result of sort:\n");for( i =11100; i < 1000000; i+= 2000){printf("%d\t", A[i]);}printf("\n");#endifreturn 0;}



结论:

    即使经过极度优化的库函数排序,也没有计数排序快,而且快了超乎寻常的18倍,效率真是令人叹为观止,所以,我们完成实际任务时,要根据具体问题选择合适的算法,没有任何算法是通用的。只有具体问题具体分析,才能得到真正的最优解。

原创粉丝点击