c语言实现小根堆

/*
** 小根堆的实现
** 逻辑模型是一个完全二叉树 存储模型是给vector
** 索引下标从0开始
**(1)如果i=0,结点i是根结点,无父结点;否则结点i的父结点为结点(i-1)/2;
**(2)如果2i+1>n-1,则结点i无左子女;否则结点i的左子女为结点2i+1;
**(3)如果2i+2>n-1,则结点i无右子女;否则结点i的右子女为结点2i+2
** 插入一个元素:新元素被加入到heap的末尾,然后更新树以恢复堆的次序。从下往上调整
** 删除一个元素:为了便于重建堆,实际的操作是将最后一个数据的值赋给根结点,堆的元素个数-1,然后再从根结点开始进行一次从上向下的调整。
*/

namespace myHeap {
        template <typename T>
        class MinHeap
        {
        private:
                unsigned int maxNodeNum, curSize;
                std::vector<T> heapDatas;
        public:
                MinHeap(unsigned int _max):
                        maxNodeNum(_max),
                        curSize(0)
                {
                        //索引下表从0开始
                        heapDatas.assign(maxNodeNum - 1,0);
                }
                MinHeap(std::vector<T> _data)
                {
                        maxNodeNum = _data.size();
                        heapDatas.assign(maxNodeNum, 0);
                        for (auto i = _data.begin(); i != _data.end(); i++)
                        {
                                insert(*i);
                        }
                }
 
                void insert(T value)
                {
                        assert(curSize + 1 <= maxNodeNum);
                        ++curSize;
                        heapDatas[curSize-1] = value;
                        recorderUpwards(curSize-1);
                }
 
                T pop()
                {
                        assert(!empty());                        
                        swap(0, curSize-1);
                        --curSize;
                        if (!curSize)
                                return heapDatas[curSize];
                        //从上往下调整堆,最后一个元素不要调整了,pop出去
                        recorderDownwards(0, curSize-1);
                        //print();
                        return heapDatas[curSize];
                }
 
                void swap(const int i,const int j)
                {
                        T temp = heapDatas[i];
                        heapDatas[i] = heapDatas[j];
                        heapDatas[j] = temp;
                }
 
                //插入数据需要从下向上调整
                //index 从index一直调整到0
                void recorderUpwards(uint index)
                {
                        while (index>0 && heapDatas[(index-1)/2]>heapDatas[index])
                        {
                                swap(index, (index - 1) / 2);
                                index = (index - 1) / 2;
                        }
                }
                //删除数据从上向下调整
                //从begin位置调整到end位置
                void recorderDownwards(uint begin,uint end)
                {
                        while (2*begin+1 <= end)
                        {
                                uint child = 2 * begin + 1;
                                //取两个子节点中比较小的进行比较调换
                                if ((child < end) && (heapDatas[child] > heapDatas[child+1]))
                                        child++;
 
                                if (child <= end)
                                {
                                        if (heapDatas[begin] > heapDatas[child])
                                        {
                                                swap(begin, child);
                                                begin = child;
                                        }
                                        else
                                                break;
                                }
                                else
                                        break;
                        }
                }
 
                bool empty() { return curSize == 0; }
                void print()
                {
                        for (int i = 0; i < getSize(); i++)
                        {
                                std::cout << heapDatas[i] << " ";
                        }
                        std::cout << std::endl;
                }
                std::vector<T>& get() { return heapDatas; } const
                uint getSize() { return curSize; }
        };
 
 
        void test()
        {
                std::vector<int> v = { 1,4,6,2,3,8, 2,11,123,13,24,13,14,14 };
                MinHeap<int> h(v);
                h.print();
                auto datas = h.get();
                uint size = h.getSize();
                for (uint i = 0; i < size; i++)
                {
                        std::cout << "pop:" << h.pop() << std::endl;
                }
                std::cout << std::endl;
        }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值