• Priority Queues优先级队列详解


    概述

    STL中 class priority_queue<>实作出一个queue,其中的元素根据优先级被读取,top() / pop()移除/存取下一个元素。这里的“下一个元素”是指“优先级最高”的元素。即priority_queue内的元素已经根据其值进行了排序。

    在priority_queue和queue都定义于头文件<queue>

    namespace std
    {
    	template <class T,
    	          class Container = vector<T> ,
    			  Class Compare = less<tyname Container::value_type> >
    	Class priority_queue;
    }


    第一个template参数是元素类型,第二个template参数定义了内部元素实际存放的容器,默认是vector,但必须要支持存取随机迭代器。第三个template参数是“用以搜寻下一个最高优先级元素”的排序准则。默认是以operator<作为比较标准,图1展示了priority_queue的接口。

    核心接口

    priority_queue的核心接口主要由成员函数push(),top(),pop()组成:
    push()
    • 将一个元素置入priority_queue内.
    pop()
    • 移除priority_queue中“优先级最高”的元素,如果存在多个相等的元素,则无法确知会移除哪一个.
    • 调用者保证priority_queue非空.
    • 该函数无返回值,想处理被移除的元素,需要调用top().
    top()
    • 从priority_queue中返回“优先级最高的元素”,如果存在多个相等的元素,则无法确知会返回哪一个.
    • 调用者必须保证priority_queue非空,否则会导致未定义行为.

    源码实现

    template<class _Ty,
    	class _Container = vector<_Ty>,
    	class _Pr = less<typename _Container::value_type> >
    	class priority_queue
    	{	// priority queue implemented with a _Container
    public:
    	typedef _Container container_type;
    	typedef typename _Container::value_type value_type;
    	typedef typename _Container::size_type size_type;
    	typedef typename _Container::reference reference;
    	typedef typename _Container::const_reference const_reference;
    
    	priority_queue()
    		: c(), comp()
    		{	// construct with empty container, default comparator
    		}
    
    	explicit priority_queue(const _Pr& _Pred)
    		: c(), comp(_Pred)
    		{	// construct with empty container, specified comparator
    		}
    
    	priority_queue(const _Pr& _Pred, const _Container& _Cont)
    		: c(_Cont), comp(_Pred)
    		{	// construct by copying specified container, comparator
    		make_heap(c.begin(), c.end(), comp);
    		}
    
    	template<class _Iter>
    		priority_queue(_Iter _First, _Iter _Last)
    		: c(_First, _Last), comp()
    		{	// construct by copying [_First, _Last), default comparator
    		make_heap(c.begin(), c.end(), comp);
    		}
    
    	template<class _Iter>
    		priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred)
    		: c(_First, _Last), comp(_Pred)
    		{	// construct by copying [_First, _Last), specified comparator
    		make_heap(c.begin(), c.end(), comp);
    		}
    
    	template<class _Iter>
    		priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred,
    			const _Container& _Cont)
    		: c(_Cont), comp(_Pred)
    		{	// construct by copying [_First, _Last), container, and comparator
    		c.insert(c.end(), _First, _Last);
    		make_heap(c.begin(), c.end(), comp);
    		}
    
    	bool empty() const
    		{	// test if queue is empty
    		return (c.empty());
    		}
    
    	size_type size() const
    		{	// return length of queue
    		return (c.size());
    		}
    
    	const_reference top() const
    		{	// return highest-priority element
    		return (c.front());
    		}
    
    	reference top()
    		{	// return mutable highest-priority element (retained)
    		return (c.front());
    		}
    
    	void push(const value_type& _Pred)
    		{	// insert value in priority order
    		c.push_back(_Pred);
    		push_heap(c.begin(), c.end(), comp);
    		}
    
    	void pop()
    		{	// erase highest-priority element
    		pop_heap(c.begin(), c.end(), comp);
    		c.pop_back();
    		}
    
    protected:
    	_Container c;	// the underlying container
    	_Pr comp;	// the comparator functor
    	};

    应用实例

    /****************************************************************
    *函数名称:PriorityQueuesTest
    *功    能:优先级队列使用说明
    *作    者:Jin
    *日    期:2016年7月6日
    ****************************************************************/
    void PriorityQueuesTest()
    {
        priority_queue<int> PriorityQue;
        
        //insert elements into priority queue
        PriorityQue.push(66);
        PriorityQue.push(22);
        PriorityQue.push(44);
        cout <<"insert num to priority queue : 66 22 44" << endl;
    
        //read and print two elements
        cout <<"read first element and pop it: " << PriorityQue.top() << endl;
        PriorityQue.pop();
        cout << "read second element and pop it: " << PriorityQue.top() << endl;
        PriorityQue.pop();
    
        //insert three more elements
        PriorityQue.push(11);
        PriorityQue.push(55);
        PriorityQue.push(33);
        cout <<"insert num to priority queue : 11 55 33" << endl;
        
        //pop one elements without dealing data
        cout << "pop one elements" << endl;
        PriorityQue.pop();
    
        //pop and print remaining element
        cout << "pop and print remaining element:" << endl;
        while (!PriorityQue.empty())
        {
            cout << PriorityQue.top() << ' ';
            PriorityQue.pop();
        }
        cout << endl;
    }
    运行结果:


  • 相关阅读:
    面试官:别的我不管,这个JVM虚拟机内存模型你必须知道
    万字长文带你掌握Java数组与排序,代码实现原理都帮你搞明白!
    面试官:就问个Spring容器初始化和Bean对象的创建,你讲一小时了
    来吧,展示!Redis的分布式锁及其实现Redisson的全过程
    Python之OS(系统操作)模块常用函数
    Python之文件操作
    Python之小测试:用正则表达式写一个小爬虫用于保存贴吧里的所有图片
    Python值正则表达式(RE)
    Python之内建函数
    Python之switch
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468404.html
Copyright © 2020-2023  润新知