zoukankan      html  css  js  c++  java
  • 从m个数中取top n

    将题目具体一点,例如,从100个数中取出从大到小排前10的数

    方法1:使用快速排序

           因为快速排序一趟下来,小于K的数都在K的前面,大于K的数都在K的后面

           如果,小于K的数有35个,大于K的数有64个

           那么,所以我们取top 10时,只需要在前35个数中进行递归快速排序,所以不需要对所有的数进行排序

    方法2:使用堆排序

           首先在前10个数中建议一个小根堆,

           因为是小根堆,所以前10个数中最小的数在index=0上

           然后遍历从11到100的数,如果p[i]>p[0],那么交换p[i]和p[0],然后重建堆

           遍历完成后,top 10的数就是堆中

    我用10万个随机数做实验,性能分析如下:



    表示当选取top 10时,快速排序花费3833微秒,堆排序花费642微秒

    结论:

      取top n时,当n小时,堆排序比快速排序有明显的优势,当n增加时,优势减少,甚至逆转

    以下是实验代码,仅供参考



    void adjust_min_heap(int*p, int index,int max)
    {
            int target,left=2*index+1,right=left+1;
            if(right <= max)
            {
                    //左右孩子都存在,找相对较小的
                    if( p[left]


                            target=left;
                    else
                            target=right;
            }
            else if(left==max)
            {
                    //只有左孩子存在
                    target=left;
            }
            else
            {
                    return;
            }
            if(p[target]


            {
                    exchange(&p[target],&p[index]);
                    adjust_min_heap(p,target,max);
            }
    }

    void find_top_n_min_heap(int*p, int num, int *n)
    {
            //如果总的个数还不够
            if(num<=*n)
            {
                    *n=num;
                    return;
            }

            int i;
            //将前n个数调整为小根堆
            for(i=*n/2-1;i>=0;i--)
                    adjust_min_heap(p,i,*n-1);

            int j;
            for(j=*n;j
                    if(p[j]>p[0])
                    {
                            exchange(&p[j],&p[0]);
                            adjust_min_heap(p,0,*n-1);
                    }
    }


    void find_top_n_1(int*p, int begin, int end, int n)
    {
            if(begin>=end)return;
            int i = begin+1,j=end;
            while(i
            {
                    while(i=p[begin])i++;
                    while(j>begin && p[j]<=p[begin])j--;
                    if(i
                    {
                            exchange(&p[i],&p[j]);
                    }
            }
            if(p[begin]


                    exchange(&p[begin],&p[j]);
            if(end-begin==1 && n==1)
            {
                    printf("%d ",p[begin]);
                    return;
            }
            if(j-begin+1 > n)
                    find_top_n_1(p,begin,j,n);
            else if(j-begin+1 == n)
            {
                    int k;
                    for(k=begin;k<=j;k++)
                            printf("%d ",p[k]);
            }
            else if(j-begin+1 < n)
            {

                    int k;
                    for(k=begin;k<=j;k++)
                            printf("%d ",p[k]);
                    find_top_n_1(p,j+1,end,n-j+begin-1);
            }
    }
    void find_top_n_quick_sort(int*p, int num, int n)
    {
            find_top_n_1(p,0,num-1,n);
    }

  • 相关阅读:
    Python 模块 itertools
    Python 字符串的encode与decode
    python 模块 hashlib(提供多个不同的加密算法)
    暴力尝试安卓gesture.key
    hdu 1300 Pearls(DP)
    hdu 1232 畅通工程(并查集)
    hdu 1856 More is better(并查集)
    hdu 1198 Farm Irrigation(并查集)
    hdu 3635 Dragon Balls(并查集)
    hdu 3038 How Many Answers Are Wrong(并查集)
  • 原文地址:https://www.cnblogs.com/hxdoit/p/3359795.html
Copyright © 2011-2022 走看看