新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 幾種查找數(shù)組的前K個最小值的算法

        幾種查找數(shù)組的前K個最小值的算法

        作者: 時間:2016-12-01 來源:網(wǎng)絡 收藏

        /*創(chuàng)建最小堆*/
        void build_minheap(int *a, int size)
        {
        int i = PARENT(size);

        assert(a != NULL);

        for(; i >= 0; -- i)
        min_heapify(a, i, size - 1);
        }

        /*采用快速排序查找*/
        void find_Kmin_num_1(int *a , int size, int k)
        {
        int i = 0;

        assert(a != NULL);

        QuickSort(a, size);

        #if 0
        for(i = 0; i < k ; ++ i)
        printf("%d ",a[i]);

        printf("");
        #endif
        }

        /*采用快速選擇實現(xiàn)*/
        void find_Kmin_num_2(int *a, int size, int k)
        {
        int i = 0;

        assert(a != NULL);

        QuickSelect(a, size, k);

        #if 0
        for(i = 0; i < k ; ++ i)
        printf("%d ",a[i]);

        printf("");
        #endif
        }

        /*采用最大堆實現(xiàn)*/
        void find_Kmin_num_3(int *a, int size, int k)
        {
        int i = 0;

        int *b = malloc(sizeof(int)*k);

        assert(a != NULL && b != NULL);

        for(i = 0; i < k; ++ i)
        b[i] = a[i];

        build_maxheap(b,k);

        for(; i < size; ++ i)
        {
        if(a[i] < b[0])
        {
        b[0] = a[i];
        // build_maxheap(b , k);
        max_heapify(b,0,k - 1);
        }
        }
        #if 0
        for(i = 0; i < k ; ++ i)
        printf("%d ",b[i]);

        printf("");
        #endif
        }

        /*采用最小堆刪除元素的方式實現(xiàn)*/
        void find_Kmin_num_4(int *a ,int size, int k)
        {
        int i = 0;

        assert(a != NULL);

        build_minheap(a, size - 1);
        for(i = 0; i < k; ++ i)
        {
        // printf("%d ",a[0]);

        /*刪除a[0],釋放a[size - 1 - i]*/
        a[0] = a[size -1 - i];
        min_heapify(a, 0, size - 2 - i);
        }
        // printf("");
        }

        int main()
        {
        int a[LEN];
        int b[LEN];
        int c[LEN];
        int d[LEN];

        int i = 0,j = 0;

        clock_t _start;
        doubletimes = 0;

        srand((int)time(NULL));

        for(i = 0; i < LEN; ++ i)
        {
        a[i] = rand()%(LEN);
        b[i] = a[i];
        c[i] = a[i];
        d[i] = a[i];

        // printf("%d ",a[i]);
        }
        // printf("");

        _start = clock();
        find_Kmin_num_1(a,LEN,K);
        times = (double)(clock() - _start)/CLOCKS_PER_SEC;
        printf("快速排序的查找需要:%f",times);

        _start = clock();
        find_Kmin_num_2(b,LEN,K);
        times = (double)(clock() - _start)/CLOCKS_PER_SEC;
        printf("快速選擇的查找需要:%f",times);

        _start = clock();
        find_Kmin_num_3(c,LEN,K);
        times = (double)(clock() - _start)/CLOCKS_PER_SEC;
        printf("最大堆的查找需要:%f",times);

        _start = clock();
        find_Kmin_num_4(d,LEN,K);
        times = (double)(clock() - _start)/CLOCKS_PER_SEC;
        printf("最小堆的查找需要:%f",times);

        return 0;
        }

        檢測算法的性能:

        [gong@Gong-Computer interview]$ gcc -g minKnum.c -o minKnum
        [gong@Gong-Computer interview]$ ./minKnum
        快速排序的查找需要:0.130000
        快速選擇的查找需要:0.020000
        最大堆的查找需要:0.000000
        最小堆的查找需要:0.010000

        從結果可知,快速排序的算法效果最差,而最大堆的效果最好,最小堆的效果其次,但是最大堆運用了額外的內存空間。因此在內存空間限制的情況下,考慮最小堆是比較合適的。但是最大堆的思想確實很精妙的,運用了類似桶排序的性質。

        為了說明算法能否實現(xiàn)前K個最小值的查找,改變數(shù)組大小為50,并打印各個方法完成的情況,查找前10個數(shù)據(jù),實驗結果如下所示:

        [gong@Gong-Computer interview]$ ./minKnum
        15 38 14 43 31 45 42 1 32 23 43 34 9 4 45 31 25 48 8 42 40 27 36 30 32 4 11 23 47 12 24 14 1 40 8 32 36 0 35 18 26 28 2 35 35 49 17 12 48 27
        0 1 1 2 4 4 8 8 9 11
        快速排序的查找需要:0.000000
        1 9 4 8 4 11 1 8 0 2
        快速選擇的查找需要:0.000000
        11 8 9 4 2 1 8 1 4 0
        最大堆的查找需要:0.000000
        0 1 1 2 4 4 8 8 9 11
        最小堆的查找需要:0.000000

        從上面的實驗結果可知,四種方法都是實現(xiàn)了獲得前K個最小元素。


        上一頁 1 2 下一頁

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 呼伦贝尔市| 商水县| 洪湖市| 元阳县| 西和县| 宾阳县| 新闻| 延寿县| 琼结县| 龙州县| 正阳县| 宁晋县| 双鸭山市| 延寿县| 崇义县| 临泉县| 延津县| 岢岚县| 交口县| 南投县| 无锡市| 正宁县| 商洛市| 福建省| 健康| 贡觉县| 舒城县| 从江县| 兴化市| 怀仁县| 揭西县| 桦川县| 日喀则市| 丹东市| 桑植县| 青河县| 淮安市| 肇东市| 繁峙县| 遂川县| 舟山市|