一、容器适配器
stack
queue
priority_queue
stack、queue、priority_queue 都不支持任一种迭代器,它们都是容器适配器类型,stack是用vector/deque/list对象创建了一个先进后出容器;queue是用deque或list对象创建了一个先进先出容器;priority_queue是用vector/deque创建了一个排序队列,内部用二叉堆实现。
(一)、stack
首先来看示例代码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br></nobr>
|
|
#include<iostream> #include<vector> #include<list> #include<stack>
usingnamespacestd;
intmain(void)
{
stack<int,list<int>>s; for(inti=0;i<5;i++)
{
s.push(i);
}
//for(size_ti=0;i<s.size();i++) //{ //cout<<s.top()<<'';Error:size()一直在变化 //s.pop(); //}
while(!s.empty())
{
cout<<s.top()<<'';
s.pop();
}
cout<<endl; return0;
}
|
再看stack 的源码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br>
39<br>
40<br>
41<br>
42<br>
43<br>
44<br>
45<br>
46<br>
47<br>
48<br>
49<br>
50<br>
51<br>
52<br>
53<br>
54<br>
55<br>
56<br>
57<br>
58<br>
59<br>
60<br>
61<br>
62<br>
63<br>
64<br>
65<br>
66<br>
67<br>
68<br>
69<br>
70<br></nobr>
|
|
//TEMPLATECLASSstack template<class_Ty, class_Container=deque<_Ty>> classstack
{ //LIFOqueueimplementedwithacontainer public: typedef_Containercontainer_type; typedeftypename_Container::value_typevalue_type; typedeftypename_Container::size_typesize_type; typedeftypename_Container::referencereference; typedeftypename_Container::const_referenceconst_reference;
stack()
:c()
{ //constructwithemptycontainer }
explicitstack(const_Container&_Cont)
:c(_Cont)
{ //constructbycopyingspecifiedcontainer }
boolempty()const
{ //testifstackisempty return(c.empty());
}
size_typesize()const
{ //testlengthofstack return(c.size());
}
referencetop()
{ //returnlastelementofmutablestack return(c.back());
}
const_referencetop()const
{ //returnlastelementofnonmutablestack return(c.back());
}
voidpush(constvalue_type&_Val)
{ //insertelementatend c.push_back(_Val);
}
voidpop()
{ //eraselastelement c.pop_back();
}
const_Container&_Get_container()const
{ //getreferencetocontainer return(c);
}
protected:
_Containerc;//theunderlyingcontainer };
|
即有一个_Container 成员,默认是deque<_Ty> ,当然也可以传递vector, list 进去,只要支持push_back,pop_back 等接口。内部的函数实现
都借助了容器的函数,跟以前实现过的Stack 很像。
(二)、queue
先来看示例代码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br></nobr>
|
|
#include<iostream> #include<vector> #include<list> #include<stack> #include<queue>
usingnamespacestd;
intmain(void)
{ //inta[]={1,2,3,4,5}; //vector<int>v(a,a+5);
queue<int,list<int>>q; for(inti=0;i<5;i++)
{
q.push(i);
}
while(!q.empty())
{
cout<<q.front()<<'';
q.pop();
}
cout<<endl;
return0;
}
|
再来看queue 源码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br>
39<br>
40<br>
41<br>
42<br>
43<br>
44<br>
45<br>
46<br>
47<br>
48<br>
49<br>
50<br>
51<br>
52<br>
53<br>
54<br>
55<br>
56<br>
57<br>
58<br>
59<br>
60<br>
61<br>
62<br>
63<br>
64<br>
65<br>
66<br>
67<br>
68<br>
69<br>
70<br>
71<br>
72<br>
73<br>
74<br>
75<br>
76<br>
77<br>
78<br>
79<br>
80<br>
81<br>
82<br></nobr>
|
|
//TEMPLATECLASSqueue template<class_Ty, class_Container=deque<_Ty>> classqueue
{ //FIFOqueueimplementedwithacontainer public: typedef_Containercontainer_type; typedeftypename_Container::value_typevalue_type; typedeftypename_Container::size_typesize_type; typedeftypename_Container::referencereference; typedeftypename_Container::const_referenceconst_reference;
queue()
:c()
{ //constructwithemptycontainer }
explicitqueue(const_Container&_Cont)
:c(_Cont)
{ //constructbycopyingspecifiedcontainer }
boolempty()const
{ //testifqueueisempty return(c.empty());
}
size_typesize()const
{ //returnlengthofqueue return(c.size());
}
referencefront()
{ //returnfirstelementofmutablequeue return(c.front());
}
const_referencefront()const
{ //returnfirstelementofnonmutablequeue return(c.front());
}
referenceback()
{ //returnlastelementofmutablequeue return(c.back());
}
const_referenceback()const
{ //returnlastelementofnonmutablequeue return(c.back());
}
voidpush(constvalue_type&_Val)
{ //insertelementatbeginning c.push_back(_Val);
}
voidpop()
{ //eraseelementatend c.pop_front();
}
const_Container&_Get_container()const
{ //getreferencetocontainer return(c);
}
protected:
_Containerc;//theunderlyingcontainer };
|
实现跟stack 是很类似的,只是queue不能用vector 实现,因为没有pop_front 接口。
(三)、priority_queue
先来看示例代码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br></nobr>
|
|
#include<iostream> #include<functional> #include<vector> #include<list> #include<stack> #include<queue>
usingnamespacestd;
intmain(void)
{ inta[]={5,1,2,4,3};
priority_queue<int,vector<int>,greater<int>>q(a,a+5);
while(!q.empty())
{
cout<<q.top()<<'';
q.pop();
}
cout<<endl;
return0;
}
|
再来看priority_queue 的源码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br>
39<br>
40<br>
41<br>
42<br>
43<br>
44<br>
45<br>
46<br>
47<br>
48<br>
49<br>
50<br>
51<br>
52<br>
53<br>
54<br>
55<br>
56<br>
57<br>
58<br>
59<br>
60<br>
61<br>
62<br>
63<br>
64<br>
65<br>
66<br>
67<br>
68<br>
69<br>
70<br>
71<br>
72<br>
73<br>
74<br>
75<br>
76<br>
77<br>
78<br>
79<br>
80<br>
81<br>
82<br>
83<br>
84<br>
85<br>
86<br>
87<br>
88<br>
89<br>
90<br>
91<br>
92<br>
93<br>
94<br>
95<br>
96<br>
97<br>
98<br>
99<br>
100<br>
101<br></nobr>
|
|
//TEMPLATECLASSpriority_queue template<class_Ty, class_Container=vector<_Ty>, class_Pr=less<typename_Container::value_type>> classpriority_queue
{ //priorityqueueimplementedwitha_Container public: typedef_Containercontainer_type; typedeftypename_Container::value_typevalue_type; typedeftypename_Container::size_typesize_type; typedeftypename_Container::referencereference; typedeftypename_Container::const_referenceconst_reference;
priority_queue()
:c(),comp()
{ //constructwithemptycontainer,defaultcomparator }
explicitpriority_queue(const_Pr&_Pred)
:c(),comp(_Pred)
{ //constructwithemptycontainer,specifiedcomparator }
priority_queue(const_Pr&_Pred,const_Container&_Cont)
:c(_Cont),comp(_Pred)
{ //constructbycopyingspecifiedcontainer,comparator make_heap(c.begin(),c.end(),comp);
}
template<class_Iter>
priority_queue(_Iter_First,_Iter_Last)
:c(_First,_Last),comp()
{ //constructbycopying[_First,_Last),defaultcomparator make_heap(c.begin(),c.end(),comp);
}
template<class_Iter>
priority_queue(_Iter_First,_Iter_Last,const_Pr&_Pred)
:c(_First,_Last),comp(_Pred)
{ //constructbycopying[_First,_Last),specifiedcomparator make_heap(c.begin(),c.end(),comp);
}
template<class_Iter>
priority_queue(_Iter_First,_Iter_Last,const_Pr&_Pred, const_Container&_Cont)
:c(_Cont),comp(_Pred)
{ //constructbycopying[_First,_Last),container,andcomparator c.insert(c.end(),_First,_Last);
make_heap(c.begin(),c.end(),comp);
}
boolempty()const
{ //testifqueueisempty return(c.empty());
}
size_typesize()const
{ //returnlengthofqueue return(c.size());
}
const_referencetop()const
{ //returnhighest-priorityelement return(c.front());
}
referencetop()
{ //returnmutablehighest-priorityelement(retained) return(c.front());
}
voidpush(constvalue_type&_Pred)
{ //insertvalueinpriorityorder c.push_back(_Pred);
push_heap(c.begin(),c.end(),comp);
}
voidpop()
{ //erasehighest-priorityelement pop_heap(c.begin(),c.end(),comp);
c.pop_back();
}
protected:
_Containerc;//theunderlyingcontainer _Prcomp;//thecomparatorfunctor };
|
priority_queue 的实现稍微复杂一点,可以传递3个参数,而且有两个成员,comp 即自定义比较逻辑,默认是less<value_type>,在构造函数中
调用make_heap函数构造二叉堆,comp 主要是用于构造二叉堆时的判别,如果是less
则构造大堆,如果传递greater 则构造小堆.
注意,priority_queue 不能用list 实现,因为list 只支持双向迭代器,而不支持随机迭代器。
下面举个例子说明make_heap 函数的用法:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br></nobr>
|
|
#include<iostream> #include<functional> #include<vector> #include<list> #include<stack> #include<queue>
usingnamespacestd;
intmain(void)
{ inta[]={5,1,2,4,3};
make_heap(a,a+5,less<int>());
copy(a,a+5,ostream_iterator<int>(cout,""));
cout<<endl;
sort(a,a+5); //sort_heap(a,a+5,less<int>()); copy(a,a+5,ostream_iterator<int>(cout,""));
cout<<endl;
return0;
}
|
输出:
5 4 2 1 3
1 2 3 4 5
make_heap() 将容器的元素构造成二叉堆,传递的是less,即构造的是大堆,把大堆层序遍历的结果存入数组,再调用sort()
进行排序,内部调用
的实际算法不一定,可以是堆排序、插入排序、选择排序等等,跟踪进去发现调用的是插入排序;当然也可以直接指定使用堆排序
sort_heap(调用
者必须已经是堆了,也就是前面已经先调用了make_heap,而且大小堆类型得匹配),与make_heap
一样,第三个参数传递的都是函数对象的用
法。sort 和 sort_heap 默认都是从小到大排序,除非重载的版本传递了第三个参数,如下,第三个参数可以是函数指针,也可以是函数对象:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br></nobr>
|
|
//orderheapbyrepeatedlypopping,usingoperator< template<class_RanIt>inline voidsort_heap(_RanIt_First,_RanIt_Last);
//orderheapbyrepeatedlypopping,using_Pred template<class_RanIt, class_Pr>inline voidsort_heap(_RanIt_First,_RanIt_Last,_Pr_Pred);
|
传递greater 构造的是小堆,如下图所示:
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
分享到:
相关推荐
### C++ STL中Stack和Queue的使用详解 #### 一、引言 在C++标准模板库(STL)中,提供了许多高效的容器类,其中包括`stack`和`queue`。这两种容器非常适合处理需要先进后出(FILO, First In Last Out)或先进先出(FIFO,...
C++ STL Adaptor stack、queue和vector的使用 C++ STL 提供了多种容器类,包括 stack、queue 和vector 等,这些容器类都是基于 Adaptor 模式实现的。下面我们将详细介绍这些容器类的使用方法和常见操作。 Stack ...
- **栈的实现**:示例代码展示了如何使用`stack`容器适配器,包括`push()`、`pop()`、`empty()`、`top()`和`size()`函数的用法,体现栈的特性。 - **双端队列的实现**:示例代码展示了如何使用`deque`容器,以及`...
顺序容器包括 vector、deque、list 等,关联容器包括 set、multiset、map、multimap 等,容器适配器包括 stack、queue、priority_queue 等。 顺序容器是 STL 中的一种基本容器,用于存放各种类型的数据。顺序容器...
- 特殊容器如stack(栈)、queue(队列)和priority_queue(优先队列)的使用场景和操作方法。 - 泛型编程的概念,理解模板和模板函数在STL中的作用。 - STL容器和算法的性能分析,如时间复杂度和空间复杂度。 通过...
5. 适配器:适配器允许将现有容器或迭代器转换为其他形式,例如stack(栈)、queue(队列)和priority_queue(优先队列)是容器适配器,reverse_iterator(反向迭代器)是迭代器适配器。 《STL_Programmer_Guide....
5. 特殊容器和组件:如stack(栈)、queue(队列)和priority_queue(优先队列)等,它们是基于现有容器实现的抽象数据类型,Meyers会指导读者如何有效地利用它们。 6. 模板元编程:Meyers还涉及了模板元编程这一...
5. **适配器**:适配器是一种设计模式,STL中有两种主要类型的适配器:容器适配器(如stack、queue和priority_queue)和迭代器适配器。它们可以将现有的容器或迭代器转换为其他形式,以满足特定需求。 6. **内存...
STL的主要组成部分包括容器、迭代器、算法和函数对象,这些组件共同构成了一个强大的工具集,极大地简化了C++程序中的数据管理和操作。 1. 容器: - **向量(Vector)**:动态数组,支持在任意位置插入和删除元素...
5. 配接器(Adapters):如`stack`、`queue`和`priority_queue`,它们将底层容器包装成特定的抽象数据类型,简化了编程模型。 6. 适配器函数:如`bind1st`和`bind2nd`,以及`mem_fun`系列,它们用于封装成员函数,...
- 适配器类如`stack`, `queue`, `priority_queue`将基本容器转换为特定用途的数据结构。 - 容器适配器提供了一种方式,使得开发者可以使用已有的容器实现栈、队列或优先级队列的功能。 6. **智能指针** - 智能...
6. **适配器(Adapters)**:适配器可以改变容器、迭代器或函数对象的行为,如stack和queue是容器适配器,将底层的容器(如deque)转换为栈或队列;priority_queue则是优先级队列适配器。 7. **STLport的实现特点**...
适配器如`std::stack`,`std::queue`,`std::priority_queue`将基本容器转化为特定用途的数据结构。 7. **算法的使用**: `sort_test`可能展示了如何使用`std::sort`对容器进行排序,`randfunc`可能涉及随机数...
主要有四大类容器:顺序容器(如vector、deque、list)、关联容器(如set、map)、容器适配器(如stack、queue、priority_queue)以及未分类容器(如unordered_set、unordered_map)。这些容器各自有不同的特性和...
C++ STL(Standard Template Library,标准模板库)是C++编程语言中不可或缺的一部分,它提供了一组高效、灵活且可重用的容器、迭代器、算法和函数对象(也称为仿函数)。STL的主要目标是简化代码,提高性能,并遵循...
5. 配接器(Adapters):如栈(`stack`)、队列(`queue`)、优先队列(`priority_queue`)等,它们将现有容器包装成特定的抽象数据类型。 6. 适配器(Adaptors):包括迭代器适配器(如反向迭代器)和函数对象...
例如,stack和queue是基于deque的适配器,priority_queue是基于heap的适配器。侯捷会详细解析这些适配器的工作原理和使用方法。 6. **内存管理(Memory Management)**:STL容器通常使用智能指针(如auto_ptr、...
**C++ SGI版STL源码详解** STL(Standard Template Library,标准模板库)是C++编程语言中的一个重要组成部分,它提供了高效且灵活的数据结构和算法。SGI(Silicon Graphics, Inc.)公司在90年代为C++社区贡献了一...
总结来说,本文档提供了一个关于C++ STL容器的全面介绍,包括了各种容器的基本用法、构造方法以及成员函数的使用示例。这些例子可以帮助初学者更好地理解和掌握C++ STL中的容器概念,进而提高编程效率。