zoukankan      html  css  js  c++  java
  • priority_queue的简单实现

    优先级队列相对于普通队列,提供了插队功能,每次最先出队的不是最先入队的元素,而是优先级最高的元素。

    它的实现采用了标准库提供的heap算法。该系列算法一共提供了四个函数。使用方式如下:

    首先建立一个容器,放入元素:

    1 vector<int> vec;
    2 insertNums(vec, 3, 7);
    3 insertNums(vec, 5, 9);
    4 insertNums(vec, 1, 4);

    打印结果为:

    all elements
    3 4 5 6 7 5 6 7 8 9 1 2 3 4 

    然后调用make_heap(), 将容器内[begin(), end())的元素建立成堆:

    make_heap(vec.begin(), vec.end());

    打印结果为:

    after make heap
    9 8 6 7 7 5 5 3 6 4 1 2 3 4 

    然后我们调用pop_heap(),该算法必须保证[begin(),end())之间的元素已经是一个堆,

    然后它将堆顶的元素放到最后,再将[begin(),end() - 1)内的元素重新排列成堆:

    pop_heap(vec.begin(), vec.end());
    vec.pop_back();
    print(vec, "after pop heap");

    打印结果为:

    after pop heap
    8 7 6 7 4 5 5 3 6 4 1 2 3 

    接下来调用push_heap(),该算法必须保证[begin(),end() - 1)已经是一个堆,再将整个[begin(),end())调整为一个堆:

    vec.push_back(17);
    push_heap(vec.begin(), vec.end());
    print(vec, "after push heap");

    打印结果为:

    after push heap
    17 7 8 7 4 5 6 3 6 4 1 2 3 5 

    最后我们调用sort_heap(),将[begin(),end())中的元素转化为有序序列,前提是[begin(),end())已经是一个堆:

    sort_heap(vec.begin(), vec.end());
    print(vec, "after sort heap");

    打印结果为:

    after sort heap
    1 2 3 3 4 4 5 5 6 6 7 7 8 17 

    完整的测试代码为:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    template <typename T>
    void insertNums(T &t, int first, int last)
    {
        while(first <= last)
        {
            t.insert(t.end(), first);
            ++ first;
        }
    }
    
    template <typename T>
    void print(const T &t, const std::string &s = "")
    {
        cout << s << endl;
        for(typename T::const_iterator it = t.begin();
            it != t.end();
            ++ it)
            cout << *it << " ";
        cout << endl;
    }
    
    int main(int argc, char const *argv[])
    {
        vector<int> vec;
        insertNums(vec, 3, 7);
        insertNums(vec, 5, 9);
        insertNums(vec, 1, 4);
    
        print(vec, "all elements");
    
        make_heap(vec.begin(), vec.end());
        print(vec, "after make heap");
    
    
        pop_heap(vec.begin(), vec.end());
        vec.pop_back();
        print(vec, "after pop heap");
    
        vec.push_back(17);
        push_heap(vec.begin(), vec.end());
        print(vec, "after push heap");
    
        sort_heap(vec.begin(), vec.end());
        print(vec, "after sort heap");
        return 0;
    }

    根据以上算法,我们来实现优先级队列priority_queue,代码如下:

     1 #ifndef PRIORITY_QUEUE_H
     2 #define PRIORITY_QUEUE_H
     3 #include <vector>
     4 #include <algorithm>
     5 #include <functional>
     6 
     7 template <typename T,
     8           typename Container = std::vector<T>,
     9           typename Compare = std::less<typename Container::value_type> >
    10 class PriorityQueue
    11 {
    12 public:
    13     typedef typename Container::value_type     value_type;
    14     typedef typename Container::size_type     size_type;
    15     typedef Container                        container_type;
    16     typedef value_type&                     reference;
    17     typedef const value_type&                const_reference;
    18 
    19     PriorityQueue(const Compare &comp = Compare(),
    20                   const Container &cont = Container());
    21 
    22 
    23 
    24     template <typename InputIter>
    25     PriorityQueue(InputIter first, InputIter last,
    26                   const Compare &comp = Compare(),
    27                   const Container &cont = Container());
    28 
    29     void push(const value_type &val)
    30     {
    31         _cont.push_back(val);
    32         std::push_heap(_cont.begin(), _cont.end(), _comp);
    33     }
    34 
    35     void pop()
    36     {
    37         std::pop_heap(_cont.begin(), _cont.end(), _comp);
    38         _cont.pop_back();
    39     }
    40 
    41     bool empty() const { return _cont.empty(); }
    42     size_type size() const { return _cont.size(); }
    43 
    44     const_reference top() const { return _cont.front(); }
    45 
    46 private:
    47     Compare _comp;
    48     Container _cont;
    49 
    50 };
    51 
    52 template <typename T, typename Container, typename Compare>
    53 PriorityQueue<T, Container, Compare>::PriorityQueue(const Compare &comp,
    54                                                     const Container &cont)
    55         :_comp(comp), _cont(cont)
    56     {
    57         std::make_heap(_cont.begin(), _cont.end(), _comp);
    58     }
    59 
    60 
    61 template <typename T, typename Container, typename Compare>
    62 template <typename InputIter>
    63 PriorityQueue<T, Container, Compare>::PriorityQueue(InputIter first, InputIter last,
    64                                                     const Compare &comp,
    65                                                     const Container &cont)
    66     :_comp(comp), _cont(cont)
    67 {
    68     _cont.insert(_cont.end(), first, last);
    69     std::make_heap(_cont.begin(), _cont.end(), _comp);
    70 }
    71 
    72 #endif

    测试代码如下:

     1 #include "priority_queue.hpp"
     2 #include <iostream>
     3 using namespace std;
     4 
     5 int main(int argc, const char *argv[])
     6 {
     7     PriorityQueue<float> q;
     8     q.push(66.6);
     9     q.push(22.3);
    10     q.push(44.4);
    11 
    12     cout << q.top() << endl;
    13     q.pop();
    14     cout << q.top() << endl;
    15     q.pop();
    16     q.push(11.1);
    17     q.push(55.5);
    18     q.push(33.3);
    19     q.pop();
    20 
    21     while(!q.empty())
    22     {
    23         cout << q.top() << " ";
    24         q.pop();
    25     }
    26     cout << endl;
    27 
    28 
    29 
    30     return 0;
    31 }

    测试结果为:

    66.6
    44.4
    33.3 22.3 11.1 
  • 相关阅读:
    SAP UI5应用和Hybris Commerce的国际化(internationalization)支持
    PHP获取目录下面所有文件和文件夹
    php利用smtp类轻松的发送电子邮件
    Redis和Memcached的一些区别
    redis命令大全参考手册
    redis类与用法
    公共类属性使用
    php 非对称加密解密类
    RSA密钥生成与使用
    Centos下安装Lamp和vsftpd、redis
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4007429.html
Copyright © 2011-2022 走看看