stack、queue、priority_queue 都不支持任一種迭代器,它們都是容器適配器類型,stack是用vector/deque/list對象建立了一個先進後出容器;queue是用deque或list對象建立了一個先進先出容器;priority_queue是用vector/deque建立了一個排序隊列,內部用二叉堆實現。
ios
stack的源碼以下:算法
1 // TEMPLATE CLASS stack 2 template < class _Ty, 3 class _Container = deque<_Ty> > 4 class stack 5 { 6 // LIFO queue implemented with a container 7 public: 8 typedef _Container container_type; 9 typedef typename _Container::value_type value_type; 10 typedef typename _Container::size_type size_type; 11 typedef typename _Container::reference reference; 12 typedef typename _Container::const_reference const_reference; 13 14 stack() 15 : c() 16 { 17 // construct with empty container 18 } 19 20 explicit stack(const _Container &_Cont) 21 : c(_Cont) 22 { 23 // construct by copying specified container 24 } 25 26 bool empty() const 27 { 28 // test if stack is empty 29 return (c.empty()); 30 } 31 32 size_type size() const 33 { 34 // test length of stack 35 return (c.size()); 36 } 37 38 reference top() 39 { 40 // return last element of mutable stack 41 return (c.back()); 42 } 43 44 const_reference top() const 45 { 46 // return last element of nonmutable stack 47 return (c.back()); 48 } 49 50 void push(const value_type &_Val) 51 { 52 // insert element at end 53 c.push_back(_Val); 54 } 55 56 void pop() 57 { 58 // erase last element 59 c.pop_back(); 60 } 61 62 const _Container &_Get_container() const 63 { 64 // get reference to container 65 return (c); 66 } 67 68 protected: 69 _Container c; // the underlying container 70 };
即有一個_Container 成員,默認是deque<_Ty> ,固然也能夠傳遞vector, list 進去,只要支持push_back,pop_back 等接口。數組
【stack示例】less
1 #include <iostream> 2 #include <vector> 3 #include <list> 4 #include <stack> 5 6 using namespace std; 7 8 int main(void) 9 { 10 stack< int, list<int> > s; 11 //add elements 12 for(int i = 0; i < 5; i++) 13 { 14 s.push(i); 15 } 16 //print all elements 17 while(!s.empty()) 18 { 19 cout << s.top() << " "; 20 s.pop(); 21 } 22 cout << endl; 23 24 return 0; 25 }
queue的源碼:函數
1 // TEMPLATE CLASS queue 2 template < class _Ty, 3 class _Container = deque<_Ty> > 4 class queue 5 { 6 // FIFO queue implemented with a container 7 public: 8 typedef _Container container_type; 9 typedef typename _Container::value_type value_type; 10 typedef typename _Container::size_type size_type; 11 typedef typename _Container::reference reference; 12 typedef typename _Container::const_reference const_reference; 13 14 queue() 15 : c() 16 { 17 // construct with empty container 18 } 19 20 explicit queue(const _Container &_Cont) 21 : c(_Cont) 22 { 23 // construct by copying specified container 24 } 25 26 bool empty() const 27 { 28 // test if queue is empty 29 return (c.empty()); 30 } 31 32 size_type size() const 33 { 34 // return length of queue 35 return (c.size()); 36 } 37 38 reference front() 39 { 40 // return first element of mutable queue 41 return (c.front()); 42 } 43 44 const_reference front() const 45 { 46 // return first element of nonmutable queue 47 return (c.front()); 48 } 49 50 reference back() 51 { 52 // return last element of mutable queue 53 return (c.back()); 54 } 55 56 const_reference back() const 57 { 58 // return last element of nonmutable queue 59 return (c.back()); 60 } 61 62 void push(const value_type &_Val) 63 { 64 // insert element at beginning 65 c.push_back(_Val); 66 } 67 68 void pop() 69 { 70 // erase element at end 71 c.pop_front(); 72 } 73 74 const _Container &_Get_container() const 75 { 76 // get reference to container 77 return (c); 78 } 79 80 protected: 81 _Container c; // the underlying container 82 };
實現跟stack 是很相似的,只是queue不能用vector 實現,由於沒有pop_front 接口。spa
【queue示例】指針
1 #include <iostream> 2 #include <vector> 3 #include <list> 4 #include <stack> 5 #include <queue> 6 7 using namespace std; 8 9 int main(void) 10 { 11 queue< int, list<int> > q; 12 //add elements 13 for(int i = 0; i < 5; i++) 14 { 15 q.push(i); 16 } 17 //print all elements 18 while(!q.empty()) 19 { 20 cout << q.front() << " "; 21 q.pop(); 22 } 23 cout << endl; 24 25 return 0; 26 }
priority_queue的源碼:code
1 // TEMPLATE CLASS priority_queue 2 template < class _Ty, 3 class _Container = vector<_Ty>, 4 class _Pr = less<typename _Container::value_type> > 5 class priority_queue 6 { 7 // priority queue implemented with a _Container 8 public: 9 typedef _Container container_type; 10 typedef typename _Container::value_type value_type; 11 typedef typename _Container::size_type size_type; 12 typedef typename _Container::reference reference; 13 typedef typename _Container::const_reference const_reference; 14 15 priority_queue() 16 : c(), comp() 17 { 18 // construct with empty container, default comparator 19 } 20 21 explicit priority_queue(const _Pr &_Pred) 22 : c(), comp(_Pred) 23 { 24 // construct with empty container, specified comparator 25 } 26 27 priority_queue(const _Pr &_Pred, const _Container &_Cont) 28 : c(_Cont), comp(_Pred) 29 { 30 // construct by copying specified container, comparator 31 make_heap(c.begin(), c.end(), comp); 32 } 33 34 template<class _Iter> 35 priority_queue(_Iter _First, _Iter _Last) 36 : c(_First, _Last), comp() 37 { 38 // construct by copying [_First, _Last), default comparator 39 make_heap(c.begin(), c.end(), comp); 40 } 41 42 template<class _Iter> 43 priority_queue(_Iter _First, _Iter _Last, const _Pr &_Pred) 44 : c(_First, _Last), comp(_Pred) 45 { 46 // construct by copying [_First, _Last), specified comparator 47 make_heap(c.begin(), c.end(), comp); 48 } 49 50 template<class _Iter> 51 priority_queue(_Iter _First, _Iter _Last, const _Pr &_Pred, 52 const _Container &_Cont) 53 : c(_Cont), comp(_Pred) 54 { 55 // construct by copying [_First, _Last), container, and comparator 56 c.insert(c.end(), _First, _Last); 57 make_heap(c.begin(), c.end(), comp); 58 } 59 60 bool empty() const 61 { 62 // test if queue is empty 63 return (c.empty()); 64 } 65 66 size_type size() const 67 { 68 // return length of queue 69 return (c.size()); 70 } 71 72 const_reference top() const 73 { 74 // return highest-priority element 75 return (c.front()); 76 } 77 78 reference top() 79 { 80 // return mutable highest-priority element (retained) 81 return (c.front()); 82 } 83 84 void push(const value_type &_Pred) 85 { 86 // insert value in priority order 87 c.push_back(_Pred); 88 push_heap(c.begin(), c.end(), comp); 89 } 90 91 void pop() 92 { 93 // erase highest-priority element 94 pop_heap(c.begin(), c.end(), comp); 95 c.pop_back(); 96 } 97 98 protected: 99 _Container c; // the underlying container 100 _Pr comp; // the comparator functor 101 };
priority_queue 的實現稍微複雜一點,能夠傳遞3個參數,並且有兩個成員,comp 即自定義比較邏輯,默認是less<value_type>,在構造函數中調用make_heap函數構造二叉堆,comp 主要是用於構造二叉堆時的判別,若是是less 則構造大堆,若是傳遞greater 則構造小堆.
注意,priority_queue 不能用list 實現,由於list 只支持雙向迭代器,而不支持隨機迭代器。
【priority_queue示例】對象
1 #include <iostream> 2 #include <functional> 3 #include <vector> 4 #include <list> 5 #include <stack> 6 #include <queue> 7 8 using namespace std; 9 10 int main(void) 11 { 12 int a[] = {5, 1, 2, 4, 3}; 13 //creat priority_queue and initialize priority_queue 14 //less<int>構造大堆 15 //greater<int>構造小堆 16 priority_queue < int, vector<int>, less<int> > q(a, a+5); 17 18 //print all elements 19 while(!q.empty()) 20 { 21 cout << q.top() << " "; 22 q.pop(); 23 } 24 cout << endl; 25 26 return 0; 27 }
下面舉個例子說明make_heap 函數的用法:blog
1 #include <iostream> 2 #include <functional> 3 #include <algorithm>//sort() 4 #include <iterator>//ostream_iterator 5 #include <vector> 6 #include <list> 7 #include <stack> 8 #include <queue> 9 10 using namespace std; 11 12 int main(void) 13 { 14 int a[] = {5, 1, 2, 4, 3}; 15 make_heap(a, a+5, less<int>()); 16 17 //copy函數會將a,a+5區間的內的值拷貝至ostream_iterator中 18 //ostream_iterator< int >(cout, " ")是一個函數對象,其功能是依次打印ostream_iterator中的 19 //值,並以空格分割 20 copy(a, a+5, ostream_iterator< int >(cout, " ")); 21 cout << endl; 22 23 sort(a, a+5); 24 25 //copy函數會將a,a+5區間的內的值拷貝至ostream_iterator中 26 copy(a, a+5, ostream_iterator< int >(cout, " ")); 27 cout << endl; 28 29 return 0; 30 }
執行結果:
1 5 4 2 1 3 2 1 2 3 4 5
make_heap() 將容器的元素構形成二叉堆,傳遞的是less,即構造的是大堆,把大堆層序遍歷的結果存入數組,再調用sort() 進行排序,內部調用的實際算法不必定,能夠是堆排序、插入排序、選擇排序等等,跟蹤進去發現調用的是插入排序;固然也能夠直接指定使用堆排序 sort_heap(調用者必須已是堆了,也就是前面已經先調用了make_heap,並且大小堆類型得匹配),與make_heap 同樣,第三個參數傳遞的都是函數對象的用法。sort 和 sort_heap 默認都是從小到大排序,除非重載的版本傳遞了第三個參數,以下,第三個參數能夠是函數指針,也能夠是函數對象:
1 // order heap by repeatedly popping, using operator< 2 template<class _RanIt> inline 3 void sort_heap(_RanIt _First, _RanIt _Last); 4 5 // order heap by repeatedly popping, using _Pred 6 template < class _RanIt, 7 class _Pr > inline 8 void sort_heap(_RanIt _First, _RanIt _Last, _Pr _Pred);