STL概覽——棧( stack )、隊列( queue )和優先級隊列( priority_queue)

棧(stack)ios

  stack是一種先進後出(First In Last Out,FILO)的數據結構,它只有一個口,日常在咱們寫深度優先遍歷算法時,,就會用到棧,stack容許咱們增長,移除,取得最頂端元素。可是除了最頂端元素以外,沒有任何其餘方法能夠存取stack的其它元素,所以stack不容許有遍歷行爲。算法

  以某種既有容器爲底層結構,將其接口改變,使之符合 「先進後出」 的特性,造成一個 stack ,是很容易作到的。deque 是雙向開口的數據結構,若以 deque爲底部結構並封閉其頭部端口,便垂手可得造成一個 stack 。所以,SGI STL 便以 deque 做爲缺省狀況下的 stack 底部結構。數據結構

  

template <class _Tp, class _Sequence>
class stack {
public:
  typedef typename _Sequence::value_type      value_type;
  typedef typename _Sequence::size_type       size_type;
  typedef          _Sequence                  container_type;

  typedef typename _Sequence::reference       reference;
  typedef typename _Sequence::const_reference const_reference;
protected:
  _Sequence c;                                //底層容器
public:
  stack() : c() {}
  explicit stack(const _Sequence& __s) : c(__s) {}

  
  //如下徹底利用_Sequence c 的操做完成 stack 的操做
  bool empty() const { return c.empty(); }
  size_type size() const { return c.size(); }
  reference top() { return c.back(); }
  const_reference top() const { return c.back(); }
  //末端進,末端出
  void push(const value_type& __x) { c.push_back(__x); }
  void pop() { c.pop_back(); }
};

 

  stack 由於全部元素都必須遵照「先進後出」的條件,只有 stack 頂端的元素,纔有機會被外界取用,stack 不提供走訪功能,所以沒有迭代器。less

  固然還能夠以 list 做爲 stack 底層容器:函數

  

#include <iostream>
#include <string>
#include <stack>
#include <list>
using namespace std;
int main()
{  //用雙向鏈表做爲底層容器     stack<int, list<int> > temp;
    for(int i = 0; i < 10; i++)
    {
        temp.push(i);                //0 1 2 3 4 5 6 7 8 9
    }
    
    
    for(int i = 0; i < 10; i++)
    {
        printf("%d ", temp.top());    //9 8 7 6 5 4 3 2 1 0 
        temp.pop();
    }
    return 0;
}

隊列(stack)測試

  queue是一種先進先出(First In First Out,FIFO)的數據結構,它有兩個出口,queue 容許新增元素,移除元素,從最低端加入元素,取得最頂端元素。但除了最底端能夠加入,最頂端能夠取出外,沒有其餘任何方法能夠存取 queue 的其餘元素,所以 queue 不容許有遍歷行爲,也就是沒有迭代器。同棧同樣,STL裏面默認 deque 做爲缺省狀況下的 queue 底部結構:spa

  

template <class _Tp, class _Sequence>
class queue {

public:
    typedef typename _Sequence::value_type      value_type;
    typedef typename _Sequence::size_type       size_type;
    typedef          _Sequence                  container_type;

    typedef typename _Sequence::reference       reference;
    typedef typename _Sequence::const_reference const_reference;
protected:
    _Sequence c;                                //底層容器
public:
    queue() : c() {}
    explicit queue(const _Sequence& __c) : c(__c) {}

    //如下徹底利用 Sequence c 的操做完成queue操做
    bool empty() const { return c.empty(); }
    size_type size() const { return c.size(); }
    reference front() { return c.front(); }
    const_reference front() const { return c.front(); }
    reference back() { return c.back(); }
    const_reference back() const { return c.back(); }
    void push(const value_type& __x) { c.push_back(__x); }
    void pop() { c.pop_front(); }
};

 

優先級隊列(priority_queue)code

  priority_queue 是一種具備權值觀念的 queue,他容許加入新元素,移除舊元素,審視元素值等功能,一樣只支持底部加元素,頂端取元素,除此之外別無其餘存取元素途徑。但priority_queue 其內部的元素並不是按照被推入的次序排列,而是自動依照元素的權值排列,權值越高,排在越前面。缺省狀況下,priority_queue 利用max-heap 完成,後者是一個以vector表現的 complete binary tree。max-heap 能夠知足 priority_queue 所須要的 「權值從高到低自動地減排序」 的特性。blog

template <class _Tp, 
    class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>),
    class _Compare
    __STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) >
class priority_queue {

public:
    typedef typename _Sequence::value_type      value_type;
    typedef typename _Sequence::size_type       size_type;
    typedef          _Sequence                  container_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 (隱式表述堆)
    priority_queue(const _Compare& __x, const _Sequence& __s) 
        : c(__s), comp(__x) 
    { make_heap(c.begin(), c.end(), comp); }

    #ifdef __STL_MEMBER_TEMPLATES
    template <class _InputIterator>
    priority_queue(_InputIterator __first, _InputIterator __last) 
        : c(__first, __last) { make_heap(c.begin(), c.end(), comp); }

    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,
         const _Compare& __x, const _Sequence& __s)
        : c(__s), comp(__x)
    { 
        c.insert(c.end(), __first, __last);
        make_heap(c.begin(), c.end(), comp);
    }

    #else /* __STL_MEMBER_TEMPLATES */
    priority_queue(const value_type* __first, const value_type* __last) 
                    : c(__first, __last) { make_heap(c.begin(), c.end(), comp); }

    priority_queue(const value_type* __first, const value_type* __last, 
         const _Compare& __x) 
        : c(__first, __last), comp(__x)
    { make_heap(c.begin(), c.end(), comp); }

    priority_queue(const value_type* __first, const value_type* __last, 
         const _Compare& __x, const _Sequence& __c)
        : c(__c), comp(__x) 
    { 
    c.insert(c.end(), __first, __last);
    make_heap(c.begin(), c.end(), comp);
    }
    #endif /* __STL_MEMBER_TEMPLATES */

    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) 
    {
        //push_heap()是泛型算法,先利用底層的push_back() 將新元素推入末端,再重排heap
        __STL_TRY
        {
            c.push_back(__x); 
            push_heap(c.begin(), c.end(), comp);
        }
        __STL_UNWIND(c.clear());
    }
    void pop()
    {
        //pop_heap()是泛型算法,從 heap 內取出一個元素,它並非真正將元素彈出
        //而是重排 heap, 而後以底層容器的 pop_back() 取得被彈出的元素  
        __STL_TRY 
        {
            pop_heap(c.begin(), c.end(), comp);
            c.pop_back();
        }
        __STL_UNWIND(c.clear());
    }
};

 

  priority_queue 的全部元素進出都有必定規則,只有 queue 頂端的元素,也就是權值最高者,纔有機會被外界取用,priority_queue沒有迭代器。排序

  priority_queue 測試以下:

  

#include <iostream>
#include <string>
#include <queue>
#include <list>
using namespace std;
int main()
{
    
    int a[] = {0, 1,12,5,56,3,23,16}; 
    priority_queue<int> temp(a, a + 8);
    cout << "top element: " << temp.top() << endl;    //56
    
    cout << "output from top: ";
    int pd_size = temp.size();
    for(int i = 0; i < pd_size; i++)
    {
        cout << temp.top() <<" ";            //56 23 16 12 5 3 1 0
        temp.pop();
    }
    return 0;
}

  stack , queue , priority_queue 都是以底部容器完成其全部工做,而這些具備 「修改某物接口,造成另外一種風貌」 的性質的數據結構, 成爲adapter(配接器), stack , queue , priority_queue 都是容器的配接器。

相關文章
相關標籤/搜索