C++中priority_queue的模拟实现(注释详解)

                首先我们要了解什么是 priority_queue ,priority_queue 优先队列是一种数据结构,它存储了元素以及它们的优先级。在优先队列中,元素按照其优先级的顺序进行移除,优先级较高的元素首先被移除。优先队列通常使用堆数据结构来实现,这样可以实现根据优先级高低高效地插入和移除元素。

                而如何控制优先级比较就可以快速的进行建堆操作,此外,我们还可以使用不同的容器来进行实现 优先级队列。因此,看似简单的 优先级队列,我们通过 模板仿函数 的封装,也能玩出花来。话不多说,上代码。

#include<iostream>
#include<list>
#include<vector>
using namespace std;
namespace test
{
    template <class T>
    struct Less// 大堆
    //com(_con[parent],_con[child])
    {
        bool operator()(const T& x, const T& y)
        {
            return x < y;
        }
    };

    template <class T>
    struct Greater// 小堆
    {
        bool operator()(const T& x, const T& y)
        {
            return x > y;
        }
    };

    //针对 指针类型 的仿函数
    template <class T>
    struct GreaterPtr
    {
        bool operator()(const T& p1, const T& p2)
        {
            return *p1 > *p2;
        }
    };
    //仿函数可以控制比较逻辑,也可以进行多种类型之间的比较
    //每一次比较够可以通过 给定的 仿函数类型
    //进行特定的比较
    //虽然只重载了 () 但是真nb


    //当然也可以对仿函数进行 特化处理 用来针对特殊参数类型
    template <class T>
    struct Greater<T*>
    {
        bool operator()(const T* x, const T* y)
        {
            return *x > *y;
        }
    };


    //priority_queue
    template<class T, class Container = vector<T>, class Compare = less<T>>
    // Container 使用 deque 也可以适配

    //优先级队列
    class priority_queue//默认是大堆  less
    {
    public:
        void adjust_up(size_t child)
        {
            Compare com;// less<T>
            size_t parent = (child - 1) / 2;
            while (child > 0)
            {
                //if (_con[child] > _con[parent])
                // < 大堆 less       > 小堆 greater

                //if (_con[parent] < _con[child])
                if (com(_con[parent], _con[child]))//大堆 <
                {
                    swap(_con[child], _con[parent]);
                    child = parent;
                    parent = (child - 1) / 2;
                }
                else
                    break;
            }
        }
        void push(const T& x)//尾部插入,向上调整
        {
            _con.push_back(x);
            adjust_up(_con.size() - 1);//向上调整
        }
        void adjust_down(size_t parent)
        {
            Compare com;// less<T>
            size_t child = parent * 2 + 1;//左孩子
            while (child < _con.size())
            {
                //if (child + 1 < _con.size() && _con[child + 1] > _con[child])
                //if (child + 1 < _con.size() && _con[child] < _con[child+1])
                if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
                {
                    child++;//右孩子, 大堆,取较大的
                }
                //if (_con[child] > _con[parent])
                //if (_con[parent] < _con[child])
                if (com(_con[parent], _con[child]))
                {
                    swap(_con[child], _con[parent]);
                    parent = child;
                    child = parent * 2 + 1;
                }
                else
                    break;
            }
        }
        void pop()//删除堆顶,将首尾交换
        {
            swap(_con[0], _con[_con.size() - 1]);//首尾交换
            _con.pop_back();

            adjust_down(0);//向下调整
        }
        bool empty()
        {
            return _con.empty();
        }
        size_t size()
        {
            return _con.size();
        }
        const T& top()
        {
            return _con[0];
        }

    private:
        Container _con;
    };
}
int main()
{
    test::priority_queue<int,vector<int>, less<int>> pq;
    // test::priority_queue<int> pq;  等价与上,采用 缺省模板
    pq.push(50);
    pq.push(60);
    pq.push(20);
    pq.push(10);
    pq.push(40);
    pq.push(30);
    //建大堆

    while (!pq.empty())
    {
        cout << pq.top() << " ";
        pq.pop();
    }
    
    return 0;
}

运行结果:

  在priority_queue的模板中:

  template<class T, class Container = vector<T>, class Compare = less<T>>,

我们可以改变其中 默认 Container 的类型选择不同的容器来实现优先级队列,还可以通过 设置默认的 Compare 的仿函数来采用不同的 比较逻辑。可以看到,这个模拟实现的 priority_queue 有很强的自主性,其中仿函数的实现更是点睛之笔,一个简单的结构体就能实现多种类型的比较。

                最近很喜欢苏轼的一首诗《水调歌头·黄州快哉亭赠张偓佺》赠给同学们!!!!!!!!!

        落日绣帘卷,亭下水连空。知君为我新作,窗户湿青红。长记平山堂上,欹枕江南烟雨,杳杳没孤鸿。认得醉翁语,“山色有无中”。 
  一千顷,都镜净,倒碧峰。忽然浪起,掀舞一叶白头翁。堪笑兰台公子,未解庄生天籁,刚道有雌雄。一点浩然气,千里快哉风。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值