C++之priority_queue

来源:互联网 发布:linux wifi发送at指令 编辑:程序博客网 时间:2024/06/07 07:34

前言

最近越来越觉得自己总结的事情越来越流水账,因此,我需要提高我总结内容的精度。所以可能会导致写博客的时间会延长一些。

之前从没用过优先队列,刷算法题目的时候才开始了解的,所以做个总结。什么情况下使用呢?比如当你需要获取到最大最小值元素,而又不想用最大最小堆的原生实现,STL提供给你更加简单的库,就是priority_queue,其时间复杂度也只有o(nlogn)。

说明

根据元素的优先级被读取,这个优先级取决于你设置的排序函数,如果你没设置,缺省的排序法则则是利用operator<形成降序排列,也就是从大到小排列的大顶堆,第一个自然就是最大的元素。还有如果你没设置保存数据的容器Container的话,默认用的是vector。

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

priority_queue提供了三个基本函数,分别是:

  1. top()
  2. push()
  3. pop()

注意,pop并不会返回元素,top才会返回堆顶的元素。

STL提供了仿函数greater<>,less<>,简化了自己再定义排序函数的过程。如果你想使用自己定义的结构,而不想使用基本数据类型,也是ok的,不过你需要在你自定义的类中重载运算符,比如:

class Student{    int id;    char name[20];    bool gender;    bool operator < (Student &a) const    {        return id > a.id;    }};

使用

这是一个找输入流的中间值的题目,用最大最小堆实现。

priority_queue<int, vector<int>, less<int>> maxHeap; //存储小的值,值越大,优先级越高priority_queue<int, vector<int>, greater<int>> minHeap; //存储大的值,值越小,优先级越高/** *  完全不需要判断各种判断 *  不过一定要注意minHeap和maxHeap的优先级顺序,避免弄反了 */void addNum3(int num) {    minHeap.push(num);    maxHeap.push(minHeap.top());    minHeap.pop();    // 平衡    if (minHeap.size() < maxHeap.size()) {        minHeap.push(maxHeap.top());        maxHeap.pop();    }}    double findMedian3() {    return maxHeap.size() == minHeap.size() ? (double)(maxHeap.top() + minHeap.top())/2.0 : (double)minHeap.top()/1.0;}    void test() {    this->addNum3(1);    this->addNum3(2);        cout << this->findMedian3() << endl;        this->addNum2(3);        cout << this->findMedian3() << endl;}

底层实现

显然,我们可以看出priority_queue的底层实现是堆实现的。里面的c就是你自己提供的容器Container。

void push(value_type&& _Val)    {    // insert element at beginning    c.push_back(_STD move(_Val));    push_heap(c.begin(), c.end(), comp);    }template<class... _Valty>    void emplace(_Valty&&... _Val)    {    // insert element at beginning    c.emplace_back(_STD forward<_Valty>(_Val)...);    push_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());    }void push(const value_type& _Val)    {    // insert value in priority order    c.push_back(_Val);    push_heap(c.begin(), c.end(), comp);    }void pop()    {    // erase highest-priority element    pop_heap(c.begin(), c.end(), comp);    c.pop_back();    }



0 0
原创粉丝点击