欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

堆的創(chuàng)建&堆排序&堆的應(yīng)用

  1. 堆的創(chuàng)建

    網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了景谷免費建站歡迎大家使用!

堆其實是一種完全二叉樹,堆分為大堆和小堆,當(dāng)滿足Key[i]>Key[2i+1]以及Key[i]>Key[2i+2]時是大堆,當(dāng)滿足Key[i]<Key[2i+1]以及Key[i]<Key[2i+2]時是小堆。

#pragma once
#include<vector>
#include<iostream>
#include<assert.h>
using namespace std;
template<class T>
class Heap
{
public:
    Heap()
        :_a(NULL)
    {}

    Heap(const T* a,size_t size)
    {
        assert(a);
        for(size_t i=0;i<size;i++)
        {
            _a.push_back(a[i]);
        }
        for(int i=(_a.size()-2)/2;i>0;--i)
        {
            _AdjustDown(i);
        }
    }
    void Push(const T& x)
    {
        _a.push_back(x);
        _AjustUp(_a.size()-1);
    }
    void Pop()
    {
        assert(_a.empty());
        swap(_a[0],_a[a.size()-1]);
        _AdjustDown();
    }
protected:
    void _AdjustDown(size_t parent)
    {
        size_t child = parent*2+1;
        while(child > 0)
        {
            if(_a[child] < _a[child+1] && child<_a.size())
            {
                ++child;//如果左孩子比有孩子大的話,不做處理,反之,使得大的變成child = child+1;
            }
            if(_a[child]>_a[parent])   //每次交再向下調(diào)整
            {
                swap(_a[child],_a[parent]);
                parent = child;
                child = parent*2+1;
            }
            else 
            {
                break;
            }
        }
    }
    void _AjustUp(size_t child)
    {    
        int parent =  (child-1)/2;
        while(child > 0)  //這里必須判斷孩子下標(biāo),否則很危險。如果要用父親的判斷,則應(yīng)該把size_t改為int
        {
            if(_a[parent]<_a[child])
            {
                swap(_a[parent],_a[child]);
                child = parent;
                parent = (child-1)/2;
            }
            else
            {
                break;
            }
        } 
    }
protected:
    vector<T> _a;
};
void TestHeap()
{
    int a[] = {10,11,13,12,16,18,15,17,14,19};
    Heap<int> Hp1(a,sizeof(a)/sizeof(a[0]));
    Hp1.Push(20);
}
int main()
{
     TestHeap();
    system( "pause");
    return 0;
}

2.堆排序思想

利用大根堆小根堆堆頂元素是最大記錄(最小記錄),使得每次從無序中選擇最大(最小記錄)就變得簡單了。這里采用大根堆思想,

1)將初始待排序關(guān)鍵字序列(R1,R2....Rn)構(gòu)建成大頂堆,此堆為初始的無序區(qū);

2)將堆頂元素R[1]與最后一個元素R[n]交換,此時得到新的無序區(qū)(R1,R2,......Rn-1)和新的有序區(qū)(Rn),且滿足R[1,2...n-1]<=R[n]; 

3)由于交換后新的堆頂R[1]可能違反堆的性質(zhì),因此需要對當(dāng)前無序區(qū)(R1,R2,......Rn-1)調(diào)整為新堆,然后再次將R[1]與無序區(qū)最 后一個元素交換,得到新的無序區(qū)(R1,R2....Rn-2)和新的有序區(qū)(Rn-1,Rn)。不斷重復(fù)此過程直到有序區(qū)的元素個數(shù)為n-1,則整個排 序過程完成。

//堆排序
#include<iostream>
#include<assert.h>
using namespace std;
void AjustDown(int a[],size_t n,int parent)
{
    assert(a);
    int child = parent*2+1;
    while(child<n)
    {
        if(child<n &&(a[child]<a[child+1]))
        {
            ++child;
        }
        if(a[child]>a[parent])
        {
            swap(a[child],a[parent]);
            parent = child;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(int a[],size_t n)
{
    assert(a);
    for(int i=(n-2)/2;i>0;--i)
    {
        AjustDown(a,n,i);
    }
    for(int i = 0; i < n; ++i)
    {
        swap(a[0],a[n-i-1]);
        AjustDown(a,n-i-1,0);
    }
}
void Test()
{
    int a[]={2,1,4,3,5,6,0,4,7,8,9};
    HeapSort(a,sizeof(a)/sizeof(a[0]));
}
int main()
{
    Test();
    system("pause");
    return 0;
}

算法分析:

從上述過程可知,堆排序其實也是一種選擇排序,是一種樹形選擇排序。只不過直接選擇排序中,為了從R[1...n]中選擇最大記錄,需比較n-1次,然后 從R[1...n-2]中選擇最大記錄需比較n-2次。事實上這n-2次比較中有很多已經(jīng)在前面的n-1次比較中已經(jīng)做過,而樹形選擇排序恰好利用樹形的 特點保存了部分前面的比較結(jié)果,因此可以減少比較次數(shù)。對于n個關(guān)鍵字序列,最壞情況下每個節(jié)點需比較log2(n)次,因此其最壞情況下時間復(fù)雜度為 nlogn。堆排序為不穩(wěn)定排序,不適合記錄較少的排序。

3.堆的應(yīng)用

例:100W個數(shù)中找出最大的100個

1  小根堆;
2  堆固定大小為100;
3  堆元素個數(shù)小于100時直接加入堆;
4  堆元素個數(shù)等于100時,與堆頂元素比較,比堆頂元素大的進(jìn)堆,并調(diào)整堆;
5  遍歷結(jié)束時,堆中元素為100個最大數(shù)。

#pragma once
#include<iostream>
#include<assert.h>
#include<time.h>
#include<stdlib.h>
using namespace std;
const int N = 10000;
const int K = 100;
void _AjustDown(int TopK[],int size,int parent)
{
    assert(TopK);
    int child = parent*2+1;
    while( child < size)
    {
        if(child < size && (TopK[child] < TopK[child+1]))
        {
            ++child;
        }
        if(TopK[child] > TopK[parent])
        {
            swap(TopK[child],TopK[parent]);
            parent = child;
        }
        else
        {
            break;
        }
    }
}
void GetTop(int a[])
{
    assert(K < N);
    int TopK[K];
    for(int i=0;i<K;++i)
    {
        TopK[i] = a[i];
    }
    //建堆
    for(int i = (K-2)/2;i>= 0;--i)
    {
        _AjustDown(TopK,K,0);
    }
    for(int i=0;i<K;++i)
    {
        cout<<TopK[i]<<" ";
    }
}

void TestTopK()
{
    srand(time(0));
    int a[N];
    int TopK[K];
    
    for(int i= 0;i<N;++i)
    {
        a[i] = rand()%10000;
    }
    for(int i = N-K;i<N;++i)
    {
        a[i] = 10000+i;
    }
    GetTop(a);
}
int main()
{
    TestTopK();
    system("pause");
    return 0;
}

名稱欄目:堆的創(chuàng)建&堆排序&堆的應(yīng)用
文章位置:http://chinadenli.net/article10/iegddo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、定制網(wǎng)站、用戶體驗企業(yè)建站、做網(wǎng)站、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管
午夜成年人黄片免费观看| 欧美欧美日韩综合一区| 国产大屁股喷水在线观看视频| 国产又粗又猛又大爽又黄| 久久精品国产99精品亚洲| 欧美精品一区二区三区白虎| 日本和亚洲的香蕉视频| 99久免费精品视频在线观| 亚洲精品成人福利在线| 亚洲永久一区二区三区在线| 日本不卡片一区二区三区| 91精品视频全国免费| 真实偷拍一区二区免费视频| 色婷婷国产精品视频一区二区保健| 老司机精品视频在线免费看 | 亚洲精品国男人在线视频| 国产精品一区二区有码| 亚洲中文字幕在线综合视频| 午夜精品在线视频一区| 久久国内午夜福利直播| 久久国产亚洲精品赲碰热| 成人免费观看视频免费| 亚洲国产欧美精品久久| 高清在线精品一区二区| 国产成人亚洲欧美二区综| 人妻内射在线二区一区| 国产又黄又爽又粗视频在线| 亚洲最大的中文字幕在线视频 | 日韩精品一区二区三区av在线| 亚洲一区二区亚洲日本| 国产欧美一区二区色综合| 正在播放国产又粗又长| 少妇毛片一区二区三区| 欧美午夜性刺激在线观看| 亚洲天堂精品1024| 在线懂色一区二区三区精品| 亚洲国产黄色精品在线观看| 国产亚洲欧美另类久久久| 亚洲伊人久久精品国产| 午夜福利92在线观看| 欧美乱视频一区二区三区|