1. 栈和队列的行为特征
- 栈和队列与数组或 list 极其相似,但对插入、访问和删除元素的方式有一定的限制。可将元素插入到什么位置以及可从什么位置删除元素决定了容器的行为特征
1.1 栈
1.2 队列
2. 使用STL stack 类
2.1 实例化stack
template<
class elementType,
class Container = deque<Type>
> class stack;
- 参数 elementType 是stack 存储的对象类型
- 第二个模板参数 Container 是 stack 使用的默认底层容器实现类
- stack 默认在内部使用 std::deque 来存储数据,但可指定使用 vector 或 list 来存储数据
#include
#include
int main () {
using namespace std;
stack<int> numsInStack;
stack<double> dblsInStack;
stack<double, vector<double> > doublesStackedInVec;
stack<int> numsInStackCopy(numsInStack);
return 0;
}
2.2 stack 的成员函数
- stack 改变了另一种容器(如 deque、list 或 vector)的行为,通过限制元素插入或删除的方式实现其功能,从而提供严格遵守栈机制的行为特征
- std::stack 的成员函数
函数 |
描述 |
push() |
在栈顶插入元素 numsInStack.push (25); |
pop() |
删除栈顶的元素 numsInStack.pop ( ); |
empty() |
检查栈是否为空并返回一个布尔值 if (numsInStack.empty ( )) DoSomething ( ); |
size() |
返回栈中的元素数 size_t numElements = numsInStack.size ( ); |
top() |
获得指向栈顶元素的引用 cout << "Element at the top = " << numsInStack.top ( ); |
2.3 使用 push() 和 pop() 在栈顶插入和删除元素
#include
#include
int main () {
using namespace std;
stack<int> numsInStack;
cout << "Pushing {25, 10, -1, 5} on stack in that order:" << endl;
numsInStack.push(25);
numsInStack.push(10);
numsInStack.push(-1);
numsInStack.push(5);
cout << "Stack contains " << numsInStack.size() << " elements" << endl;
while (numsInStack.size() != 0) {
cout << "Popping topmost element: " << numsInStack.top() << endl;
numsInStack.pop();
}
if (numsInStack.empty()) {
cout << "Popping all elements empties stack!" << endl;
}
return 0;
}
3. 使用STL queue 类
- STL queue 是一个模板类,要使用它,必须包含头文件 queue
- queue 是一个泛型类,只允许在末尾插入元素以及从开头删除元素
- queue 不允许访问中间的元素,但可以访问开头和末尾的元素
3.1 实例化queue
template <
class elementType,
class Container = deque<Type>
> class queue;
- 其中 elementType 是 queue 对象包含的元素的类型
- Container 是 std::queue 用于存储其数据的集合类型,可将该模板参数设置为 std::list、vector 或 deque,默认为 deque
#include
#include
int main () {
using namespace std;
queue<int> numsInQ;
queue<double> dblsInQ;
queue<double, list<double> > dblsInQInList;
queue<int> copyQ(numsInQ);
return 0;
}
3.2 queue 的成员函数
函数 |
描述 |
push() |
在队尾(即最后一个位置)插入一个元素 |
pop() |
将队首(即最开始位置)的元素删除 |
front() |
返回指向队首元素的引用 |
back() |
返回指向队尾元素(即最后插入的元素)的引用 |
empty() |
检查队列是否为空并返回一个布尔值 |
size() |
返回队列中的元素数 |
STL queue 没有提供 begin() 和 end() 等函数,这是有意为之的,旨在只允许对 queue 执行符合队列行为特征的操作
3.3 使用 push() 在队尾插入以及使用 pop() 从队首删除
#include
#include
int main () {
using namespace std;
queue<int> numsInQ;
cout << "Inserting {10, 5, -1, 20} into queue" << endl;
numsInQ.push(10);
numsInQ.push(5);
numsInQ.push(-1);
numsInQ.push(20);
cout << "Queue contains " << numsInQ.size() << " elements" << endl;
cout << "Element at front: " << numsInQ.front() << endl;
cout << "Element at back: " << numsInQ.back() << endl;
while (numsInQ.size() != 0) {
cout << "Deleting element: " << numsInQ.front() << endl;
numsInQ.pop();
}
if (numsInQ.empty()) {
cout << "The queue is now empty!" << endl;
}
return 0;
}
4. 使用STL 优先级队列
- STL priority_queue 是一个模板类,要使用它,也必须包含头文件 queue
- priority_queue 与 queue 的不同之处在于,包含最大值(或二元谓词认为是最大值)的元素位于队首,且只能在队首执行操作
4.1 实例化priority_queue 类
template <
class elementType,
class Container=vector<Type>,
class Compare=less<typename Container::value_type>
> class priority_queue;
- 其中 elementType 是一个模板参数,指定了优先级队列将包含的元素的类型
- 第二个模板参数指定 priority_queue 在内部将使用哪个集合类来存储数据
- 第三个参数让程序员能够指定一个二元谓词,以帮助队列判断哪个元素应位于队首,。如果没有指定二元谓词,priority_queue 类将默认使用 std::less,它使用运算符 < 比较对象
#include
#include
int main () {
using namespace std;
priority_queue<int> numsInPrioQ;
priority_queue<double> dblsInPrioQ;
priority_queue<int, deque<int>, greater<int> > numsInDescendingQ;
priority_queue<int> copyQ(numsInPrioQ);
return 0;
}
4.2 priority_queue 的成员函数
函数 |
描述 |
push() |
在优先级队列中插入一个元素 |
pop() |
删除队首元素,即最大的元素 |
top() |
返回指向队列中最大元素(即队首元素)的引用 |
empty() |
检查优先级队列是否为空并返回一个布尔值 |
size() |
返回优先级队列中的元素个数 |
4.3 使用push()在priority_queue末尾插入以及使用pop()在priority_queue开头删除
#include
#include
int main () {
using namespace std;
priority_queue<int> numsInPrioQ;
cout << "Inserting {10, 5, -1, 20} into the priority_queue" << endl;
numsInPrioQ.push(10);
numsInPrioQ.push(5);
numsInPrioQ.push(-1);
numsInPrioQ.push(20);
cout << "Deleting the " << numsInPrioQ.size() << " elements" << endl;
while (!numsInPrioQ.empty()) {
cout << "Deleting topmost element: " << numsInPrioQ.top() << endl;
numsInPrioQ.pop();
}
return 0;
}
- 通过使用谓词将值最小的元素放在 priority_queue 开头
#include
#include
#include
int main () {
using namespace std;
priority_queue<int, vector<int>, greater<int> > numsInPrioQ;
cout << "Inserting {10, 5, -1, 20} into the priority queue" << endl;
numsInPrioQ.push(10);
numsInPrioQ.push(5);
numsInPrioQ.push(-1);
numsInPrioQ.push(20);
cout << "Deleting " << numsInPrioQ.size() << " elements" << endl;
while (!numsInPrioQ.empty ()) {
cout << "Deleting topmost element " << numsInPrioQ.top () << endl;
numsInPrioQ.pop ();
}
return 0;
}
Q&A
- 能否对队列中的所有元素进行迭代?
- STL 算法能否用于自适应容器?
- STL 算法使用迭代器。由于 stack 和 queue 类都没有提供标记范围两端的迭代器,因此无法将 STL 算法用于这些容器