中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

【數據結構】用模版實現大小堆、實現優先級隊列,以及堆排序

發布時間:2020-07-26 12:23:06 來源:網絡 閱讀:732 作者:安下 欄目:編程語言

    一、用模版實現大小堆


    如果不用模版的話,寫大小堆,就需要分別實現兩次,但是應用模版的話問題就簡單多了,我們只需要實現兩個仿函數,Greater和Less就行了,仿函數就是用類實現一個()的重載就實現了仿函數。這個看下代碼就能理解了。再設計參數的時候,需要把模版設計成模版的模版參數,因為要實現大小堆嘛!當我們實現好一個大堆或者小隊的邏輯后只需要用模版接收的Greater或Less類定義一個變量,就能實現通用功能了。


template<typename T>
struct Less
{
    bool operator()(const T& l, const T& r)
    {
        return l < r;
    }
};

template<class T>
struct Greater
{
    bool operator()(const T& l, const T& r)
    {
        return l>r;
    }
};

template <class T,template<class> class compare = less>
class Heap
{
public:
    Heap()
    {}

    Heap(T* a,size_t size)
    {
        size_t index = 0;
        while (index < size)
        {
            _a.push_back(a[index]);
            index++;
        }

        for (int i = (_a.size() - 2) / 2; i >= 0; i--)
            _AdjustDown(i);
    }

    void push(const T& x)
    {
        _a.push_back(x);
        _AdjustUp(_a.size() -1);
    }

    void pop()
    {
        size_t size = _a.size();
        assert(size > 0);
        swap(_a[0], _a[size - 1]);
        _a.pop_back();
        size = _a.size();
        _AdjustDown(0);
    }

    size_t top()
    {
        assert(!_a.empty());

        return _a[0];
    }

    bool empty()
    {
        return _a.size() == 0;
    }

    size_t Size()
    {
        return _a.size();
    }

    void Print()
    {
        for (int i = 0; i < _a.size(); i++)
        {
            cout << _a[i] << " ";
        }
        cout << endl;
    }

protected:
    void _AdjustUp(int child)
    {
        int parent = (child - 1) / 2;
        compare<T> com;  //如果是大堆傳過來就是用大堆的邏輯,小堆就實現小堆的邏輯
        while (child > 0)
        {
            //找出孩子中的最大孩子
            if (com(_a[child] , _a[parent]))
            {
                swap(_a[child], _a[parent]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
            {
                break;
            }
        }

    }

    void _AdjustDown(size_t parent)
    {
        size_t child = 2 * parent + 1;
        compare<T> com; //如果是大堆傳過來就是用大堆的邏輯,小堆就實現小堆的邏輯
        while (child < _a.size())
        {
            //找出孩子中的最大孩子
            if (child + 1 < _a.size() && com(_a[child+1] ,_a[child]))
            {
                ++child;
            }
            //把
            if (com(_a[child] , _a[parent]))
            {
                swap(_a[parent], _a[child]);
                parent = child;
                child = child * 2 + 1;
            }
            else
            {
                break;
            }
        }

    }
protected:
    vector<T> _a;
};


   二、用模版實現優先級隊列


前面實現了大小堆,這里我們可以使用適配器,直接調用大小堆,來實現優先級隊列。


template<class T, template<class> class compare = Less>
class priorityQueue
{
private:
    Heap<T, compare> _hp; 
public:
    void push(const T& x)
    {
        _hp.push(x);
    }

    void pop()
    {
        _hp.pop();
    }

    T& Top()
    {
        return _hp.top();
    }

    void Print()
    {
        _hp.Print();
    }

};


    三、堆排序的實現


    堆排序的實現簡單思路,(升序)先構造出來一個大堆,調整堆后,將堆頭和最后一個數據交換,最大值就換到了數組的最后,然后在調整堆,但是size需要減少1,因為最大的已經調整到最后,如果再加上它調整又會回到堆頭。

int*& HeapSort(int* a, size_t size)
{
    for (int i = (size - 2) / 2; i >= 0; i--)
    {
        _AdjustDown(a, size, i);
    }

    for (int i = 0; i < size; i++)
    {
        swap(a[0], a[size - i - 1]);
        _AdjustDown(a, size - i - 1, 0);
    }

    return a;
}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

启东市| 延吉市| 库尔勒市| 隆化县| 永平县| 麻江县| 如皋市| 永仁县| 青浦区| 靖西县| 基隆市| 永安市| 兴业县| 津市市| 桂平市| 隆德县| 和硕县| 昌黎县| 博客| 台中县| 永泰县| 滁州市| 方正县| 隆化县| 和田县| 象州县| 浙江省| 深泽县| 白水县| 盱眙县| 河东区| 唐河县| 彩票| 松潘县| 东辽县| 汕尾市| 泰兴市| 炎陵县| 延川县| 金溪县| 东兰县|