C++STL之stack与queue:
STL提供了三种容器适配器:stack ,queue , priority_queue。这些容器成为容器适配器,由顺序容器变化而来。不支持迭代器操作。在使用栈,队列的时候可以调用STL中的模板,可以在一程度上简化代码,但是可能会引来效率的降低。
stack:
头文件:#include<stack>
1.创建一个栈对象:
stack<T,C> s ; //创建一个数据类型为T类型的栈s,该栈基于C实现,T可以是基本的数据类型也可以是自定义的数据类型,而C可以是vector,deque或者list,默认情况下deque实现
如:stack<int> s ;//创建一个int型的栈,默认使用deque实现。
stack<int , vector<int>> s ;//创建一个int型的栈,由vector实现。
2.push(T t) ;//向栈中添加一个元素。
3.pop() ;//删除栈顶元素
4.top();//返回栈顶元素
5.size();//返回栈的大小
6.empty() ;//若栈为空,则返回真
queue:
头文件:#include<queue>
同stack一样可以由deque或者list来构造一个queue对象,默认情况下由deque实现。
1.创建一个queue对象
queue<T , C> Q ; //创建一个T类型的由C实现的队列Q。
类型T可以是基本数据类型,也可以是自定义的数据类型。C可以是list也可以是deque。例如:queue<int> q1 ;//创建一个int型的队列q1,基于deque实现。queue<int ,list<int>> q2 ;//创建一个基于list实现的队列。
2.push(T t) ;//将数据t插入到队尾
3.pop();//删除队首元素
4.front();//返回队首元素,但不删除
5.back() ;//返回队尾元素,但不删除
6.size() ;//返回队列的大小
7.empty() ;//若队列为空返回真
priority_queue:
头文件:#include<queue>
优先队列中,每个元素都被赋予一个优先级,优先级最高的元素首先被访问/删除。优先权高的先出列。priority_queue内部是调用make_heap () , pop_heap() ,push_heap()实现,属于堆的另一中形式。
1.创建一个对象:
priority_queue<Type, Container, Functional>
其中Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,也可以通过重载operator<或者重定义less或者greater()函数
优先队列就是大顶堆,队头元素最大。
2.相关的函数调用与queue相同,再次不再赘述。
3.关于自定义优先级:
A. 基本数据类型实现最大堆,默认,此时不需要传递带三个参数。
B. 基本数据类型实现最小堆,将greater()作第三个参数传递过去,此时还需要将第二个参数传过去,否则可能导致编译错误(我在自己的机子上测试的时候没有传递第二个参数,出现编译错误),此外在第三个参数与最后的>中间需要添加一个空格,否则会当作输出流而出现编译错误,例如:
priority_queue<int, vector<int>, greater<int> > q;
如下程序:
#include<iostream>
#include<queue>
using namespace std ;
int main()
{
//priority_queue<int> q1 ;
priority_queue<int, vector<int>, greater<int> > q2 ;
int i ;
for(i = 0 ; i < 10 ; i ++)
{
q2.push(i) ;
}
while(!q2.empty())
{
cout<<q2.top()<<endl;
q2.pop() ;
}
return 0 ;
}
C. 自定义数据类型,则必须重写operator<或者实现相应的仿函数
(1) . 重载operator<,此时不需要传递第三个参数,可以传递前两个参数,第二个参数可传可不传,注意此时一定不能传递第三个参数,例如:
#include<iostream>
#include<queue>
using namespace std ;
struct Node
{
int a ;
int index ;
} ;
bool operator<(Node a , Node b)
{
return a.a < b.a ;//此时得到的将会是最大堆,优先权是Node中的//a作为衡量
}
int main()
{
priority_queue<Node> q ;
int i ;
for(i = 0 ; i < 10 ; i ++)
{
Node a ;
cin>>a.a ;
a.index = i ;
q.push(a) ;
}
while(!q.empty())
{
cout<<"a:"<<q.top().a <<"\tindex :"<<q.top().index<<endl ;
q.pop() ;
}
return 0 ;
}
(2) 实现相应的仿函数:
例如:
#include<iostream>
#include<queue>
using namespace std ;
struct Node
{
int a ;
int index ;
} ;
/*
bool operator<(Node a , Node b)
{
return a.a > b.a ;
}
*/
struct cmp//这里实现自定义的优先权
{
bool operator() (Node &a , Node &b)
{
return a.a > b.a ;
}
};
int main()
{
priority_queue<Node , vector<Node> , cmp > q ;
int i ;
for(i = 0 ; i < 10 ; i ++)
{
Node a ;
cin>>a.a ;
a.index = i ;
q.push(a) ;
}
while(!q.empty())
{
cout<<"a:"<<q.top().a <<"\tindex :"<<q.top().index<<endl ;
q.pop() ;
}
return 0 ;
}
以上三种容器适配器都没有清除函数,不能一次将对应的存储元素通过函数一次全部删除完,只能通过判断是否为空,然后不断的将元素弹出,这使得相应的效率很低。因此在选择的时候需要慎重。