堆的實現

堆結構的二叉樹存儲是

最大堆:每個父節點的都大於孩子節點。

最小堆:每個父節點的都小於孩子節點。wKioL1cxqpSB1fJZAADH4PiQyXA363.png孩子節點

















下面,我們以小堆爲例,實現堆的建立:

wKiom1cxq6KTilyeAACBl_GEqnU409.png


代碼如下:

#pragma once
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;

template<class T>
class Heap
{
public:
    Heap()
    {}
    Heap(const T* a, size_t size)
    {
        assert(a);
        for (size_t i = 0; i < size; i++)
        {
            _a.push_back(a[i]);
        }
        //建堆(從第一個非葉子節點(n-1)/2)
        for (int i = (_a.size() - 2) / 2; i >= 0; --i) //先-1求下表
        {
            _AdjustDown(i);
        }
    }
    void Push(const T& x)
    {
        _a.push_back(x);
        _AdjustUp(_a.size() - 1); //向上調整
    }
    void Pop() //刪除最大元素(與最後一個元素交換,在pop,最後向下調整)
    {
        assert(!_a.empty());
        swap(_a[0], _a[_a.size() - 1]);
        _a.pop_back();
        _AdjustDown(0);
    }
protected:
    void _AdjustDown(size_t parent)
    {
        size_t child = parent * 2 + 1;
        while (child < _a.size())
        {
            if ((child+1<_a.size())&&(_a[child] > _a[child + 1]))
            {
                child++;
            }
            if (_a[parent] > _a[child])
            {
                swap(_a[child], _a[parent]);
                parent = child;
                child = 2 * parent + 1;
            }
            else
                break;
        }
    }
    void _AdjustUp(size_t child)
    {
        size_t parent = (child - 1) / 2;
        while (child > 0)
        {
            if (_a[child] > _a[parent])
            {
                swap(_a[child], _a[parent]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
            {
                break;
            }
        }
    }
protected:
    vector<T> _a;
};

測試用例:

void test1()
{
    int a[] = { 53, 17, 18, 9, 45, 65, 87, 23 };
    int size = sizeof(a) / sizeof(a[0]);
    Heap<int> h1(a, size);
    /*h1.Push(30);
    h1.Pop();*/
 }

wKiom1cxsA-Sz_cgAAB2X3ZfYEQ013.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章