必读篇!STL序列式容器priority_queue源码剖析

一、priority_queue概述

  • 特点:priority_queue会对队列中的元素根据权值进行排序(权值默认为元素的值),权值最高的在队列的头部
  • 底层实现:
  • priority_queuequeue是一种配接器(Adapter):由于queue系以底部容器完成其所有工作,而具有这种“修改某物接口,形成另一种风貌”之性质者,称为adapter(配接器),因此 STL priority_queue往往不被归类为container(容器),而被归类为container adapter

二、priority_queue源码

template <class T, class Sequence = vector<T>,
    class Compare = less<typename Sequence::value_type> >

class priority_queue {
public:
    typedef typename Sequence::value_type value_type;
    typedef typename Sequence::size_type size_type;
    typedef typename Sequence::reference reference;
    typedef typename Sequence::const_reference const_reference;

protected:
    Sequence c; // 底层容器
    Compare comp; // 元素大小比较标准

public:
    priority_queue() : c() {}
    explicit priority_queue(const Compare& x) : c(), comp(x) {}

    // 以下用到的 make_heap(), push_heap(), pop_heap()都是泛型算法
    // 注意,任一个建构式都立刻于底层容器内产生一个 implicit representation heap
    template <class InputIterator>
    priority_queue(InputIterator first, InputIterator last, const Compare& x)
        : c(first, last), comp(x) { make_heap(c.begin(), c.end(),comp); }
    template <class InputIterator>
    priority_queue(InputIterator first, InputIterator last)
        : c(first, last) { make_heap(c.begin(), c.end(), comp); }

    bool empty() const { return c.empty(); }
    size_type size() const { return c.size(); }
    const_reference top() const { return c.front(); }
    void push(const value_type& x) {
        __STL_TRY {
            // push_heap是泛型算法,先利用底层容器的 push_back() 将新元素推入末端,再重排heap
            c.push_back(x);
            push_heap(c.begin(), c.end(), comp); //push_heap是泛型算法
        }
        __STL_UNWIND(c.clear());
    }
    void pop() {
        __STL_TRY {
            //pop_heap 是泛型算法,从 heap 内取出一个元素。它并不是真正将元素
            //弹出,而是重排 heap,然后再以底层容器的 pop_back() 取得被弹出的元素
            pop_heap(c.begin(), c.end(), comp);
            c.pop_back();
        }
        __STL_UNWIND(c.clear());
    }
};

三、priority_queue没有迭代器

  • priority_queue的所有元素,进出都有一定的规则,只有queue顶端的元素(权值最高者),才有机会被外界取用。priority_queue 不提供遍历功能,也不提供迭代器

四、演示案例

#include <iostream>
#include <queue>
#include <algorithm>

using namespace std;

int main()
{

	int arr[6] = { 4,1,7,6,2,5 };
	std::priority_queue<int> ipq(arr, arr + 6);

	std::cout << ipq.size() << std::endl; //6
	
	//因为队列只能先进先出,所以不能够遍历队列
	for (int i = 0; i < ipq.size(); ++i)
		std::cout << ipq.top();   //7 7 7 7 7 7
	std::cout << std::endl;

	//先获取队列首部元素,然后再弹出
	while (!ipq.empty()) {
		std::cout << ipq.top()<<" "; //7 6 5 1 2 4
		ipq.pop();
	}
	std::cout << std::endl;
	return 0;
}


  • 我是小董,V公众点击"笔记白嫖"解锁更多【C++ STL源码剖析】资料内容。

©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页