• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            堆優化的方法:
            1、自頂向下
            template <class Item>
            void fixDown(Item a[],int k,int N)
            {
                Item temp;
                while(2*k <= N)
                {
                    int j = 2*k;
                    if (j<N&&a[j]<a[j+1]) j++;
                    if (!(a[k]<a[j])) break;
                    //cout<<"fixdown"<<j<<endl;
                    exch(a[k],a[j]);
                    k = j;
                }
            }
            根據堆是個完全二叉樹,把除了葉節點以外的從下往上逐步排好。
            2、自底向上
            template <class Item>
            void fixUp(Item a[],int k)
            {
                while(k>1 && a[k/2]<a[k])
                {
                    exch(a[k],a[k/2]);
                    k = k/2;
                }
            }

            堆排排序的步驟,
            1、建立堆。
            可以插入的方法或者采取修正堆的方法。
              for(k=N/2;k>=l;k--)
                {
                    fixDown(pq,k,N);
                }
            2、逐步排序。
               while(N>l)
                {
                    exch(pq[l],pq[N]);
                    fixDown(pq,l,--N);
                }

            總算法:
            template <class Item>
            void heapsort(Item a[],int l,int r)
            {
                int  k = l,N = r-l+1;
                Item *pq = a+l-1;
                for(k=N/2;k>=l;k--)
                {
                    fixDown(pq,k,N);
                }
                while(N>l)
                {
                    exch(pq[l],pq[N]);
                    fixDown(pq,l,--N);
                }

            }



            堆排序引申的題目。
            如果需要找出N個數最大的K個不同的數


            N > K,前K個數中的最大K個數是一個退化的情況,所有K個數就是最大的K個數。如果考慮第K+1個數X呢?如果X比最大的K個數中的最小的數Y小,那么最大的K個數還是保持不變。如果XY大,那么最大的K個數應該去掉Y,而包含X。如果用一個數組來存儲最大的K個數,每新加入一個數X,就掃描一遍數組,得到數組中最小的數Y。用X替代Y,或者保持原數組不變。這樣的方法,所耗費的時間為ON * K)。

            進一步,可以用容量為K的最小堆來存儲最大的K個數。最小堆的堆頂元素就是最大K個數中最小的一個。每次新考慮一個數X,如果X比堆頂的元素Y小,則不需要改變原來的堆,因為這個元素比最大的K個數小。如果X比堆頂元素大,那么用X替換堆頂的元素Y。在X替換堆頂元素Y之后,X可能破壞最小堆的結構(每個結點都比它的父親結點大),需要更新堆來維持堆的性質。更新過程花費的時間復雜度為O(log2K)。

            ImageName

            圖2-1

            圖2-1是一個堆,用一個數組h[]表示。每個元素h[i],它的父親結點是h[i/2],兒子結點是h[2 * i + 1]和h[2 * i + 2]。每新考慮一個數X,需要進行的更新操作偽代碼如下:

            代碼清單2-13

            if(X > h[0])

            {

                h[0] = X;

                p = 0;

                while(p < K)

                {

                    q = 2 * p + 1;

                    if(q >= K)

                        break;

                    if((q < K – 1) && (h[q + 1] < h[q]))

                        q = q + 1;

                    if(h[q] < h[p])

                    {

                        t = h[p];

                        h[p] = h[q];

                        h[q] = t;

                        p = q;

                    }

                    else

                        break;

                }

            }

            因此,算法只需要掃描所有的數據一次,時間復雜度為ON * log2K)。這實際上是部分執行了堆排序的算法。在空間方面,由于這個算法只掃描所有的數據一次,因此我們只需要存儲一個容量為K的堆。大多數情況下,堆可以全部載入內存。如果K仍然很大,我們可以嘗試先找最大的K’個元素,然后找第K’+1個到第2 * K’個元素,如此類推(其中容量K’的堆可以完全載入內存)。不過這樣,我們需要掃描所有數據ceilK/K’)次。



            Posted on 2008-06-16 11:40 micheal's tech 閱讀(772) 評論(0)  編輯 收藏 引用 所屬分類: Algorithm
            亚洲精品无码久久久影院相关影片| 久久国产热精品波多野结衣AV| 国产成人久久精品麻豆一区| 久久超乳爆乳中文字幕| 久久精品成人免费看| 欧美性大战久久久久久| 亚洲精品美女久久久久99| 青青青国产精品国产精品久久久久 | 久久亚洲国产成人影院| 久久婷婷色香五月综合激情| 成人综合伊人五月婷久久| 久久WWW免费人成—看片| 亚洲乱码精品久久久久..| 久久国产成人| 久久狠狠高潮亚洲精品| 亚洲午夜精品久久久久久浪潮| 国内精品久久久久久久久电影网 | 久久99精品国产麻豆宅宅| 久久99热精品| 蜜臀av性久久久久蜜臀aⅴ| 久久久久久av无码免费看大片| 无码久久精品国产亚洲Av影片 | 亚洲精品国产第一综合99久久| 久久发布国产伦子伦精品| 亚洲va久久久噜噜噜久久| 一本久久综合亚洲鲁鲁五月天| 情人伊人久久综合亚洲| 久久精品国产亚洲AV无码娇色| 欧美黑人激情性久久| 午夜精品久久影院蜜桃| 精品99久久aaa一级毛片| 久久国产精品久久国产精品| 久久精品水蜜桃av综合天堂| 狠狠色噜噜色狠狠狠综合久久| 久久婷婷色综合一区二区| 成人精品一区二区久久久| 久久狠狠色狠狠色综合| 久久国产精品久久国产精品| 久久久久国产一级毛片高清版| 久久精品国产91久久综合麻豆自制| 久久精品人成免费|