在C++中,stack
和queue
是标准模板库(STL)提供的两种容器适配器。它们提供了对底层容器的有限接口,使得只能执行特定的操作。下面是关于如何使用这两种容器适配器以及一些需要注意的事项。
C++中的Stack
定义: stack
是一种后进先出(LIFO, Last In First Out)的数据结构,它只允许在栈顶进行插入或删除操作。
使用方法:
- 包含头文件:
#include <stack>
- 定义一个栈:
std::stack<T> my_stack;
其中T
是元素类型。 - 常用操作:
push(elem)
:向栈顶添加一个元素。pop()
:移除栈顶元素。top()
:访问栈顶元素。empty()
:检查栈是否为空。size()
:返回栈内元素的数量。
注意事项:
- 在调用
top()
之前确保栈非空,否则会导致未定义行为。 - 在调用
pop()
之前也应确认栈非空。 - 默认情况下,
stack
使用的底层容器是deque
,但也可以指定其他容器如vector
或list
。
C++中的Queue
先进先出(FIFO)队列
定义: queue
是一种先进先出(FIFO, First In First Out)的数据结构,新元素从队尾加入,旧元素从队首移除。
使用方法:
- 包含头文件:
#include <queue>
- 定义一个队列:
std::queue<T> my_queue;
其中T
是元素类型。 - 常用操作:
push(elem)
:将一个元素添加到队尾。pop()
:移除队首元素。front()
:访问队首元素。back()
:访问队尾元素。empty()
:检查队列是否为空。size()
:返回队列内元素的数量。
注意事项:
- 同样,在调用
front()
或back()
前要确保队列非空。 pop()
仅移除队首元素,并不会返回该元素值;若需要获取并移除,则先调用front()
再pop()
。queue
默认使用的底层容器也是deque
,可以自定义为其他容器。
优先队列 (Priority Queue)
定义:
- 优先队列是一种容器适配器,它提供常数时间的最大元素查找,并且可以在对数时间内插入或删除元素。
- 默认情况下,
priority_queue
使用的是最大堆结构,即最大的元素位于顶部。
使用方法:
-
包含头文件:
#include <queue>
-
定义一个优先队列:
std::priority_queue<T> my_pq;
使用默认比较器(大顶堆)。std::priority_queue<T, Container, Compare> my_pq;
可以指定底层容器和自定义比较器。例如,使用小顶堆可以这样定义:std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
-
常用操作:
push(elem)
:添加一个元素到队列中。pop()
:移除优先级最高的元素。top()
:访问优先级最高的元素,但不移除。empty()
:检查队列是否为空。size()
:返回队列内元素的数量。
注意事项:
- 在调用
top()
之前确保队列非空。 pop()
仅移除优先级最高的元素,并不会返回该元素值;若需要获取并移除,则先调用top()
再pop()
。- 如果你需要不同的排序规则,可以通过第三个模板参数传递一个自定义的比较函数对象。
priority_queue
的默认底层容器是vector
,但是也可以使用其他支持随机访问迭代器的容器,如deque
。
自定义比较器
你可以通过继承std::binary_function
或者直接定义一个函数对象来创建自己的比较器。例如,如果你想要创建一个基于某种特定属性的小顶堆,你可以这样做:
struct MyCompare {bool operator()(const MyClass& a, const MyClass& b) const {return a.value > b.value; // 小顶堆}
};std::priority_queue<MyClass, std::vector<MyClass>, MyCompare> pq;
在这个例子中,MyClass
是你存储在优先队列中的类类型,而value
是这个类中的一个成员变量,用于确定优先级。
总之,优先队列非常适合那些需要快速访问最大或最小元素的应用场景,比如任务调度、事件驱动模拟等。
通用注意事项
- 对于
stack
和queue
,不要尝试直接访问内部数据结构,而应该通过提供的成员函数来操作。 - 使用迭代器遍历这些容器适配器通常不是个好主意,因为它们没有提供迭代器支持。
- 当选择底层容器时要考虑性能因素,例如对于大量连续存储的需求,
vector
可能是更好的选择;而对于频繁插入删除的情况,list
可能更合适。 - 记得包含正确的头文件,并且命名空间通常是
std
,因此你可能需要使用std::
前缀或者在代码开始处使用using namespace std;
语句。
以上就是C++中stack
和queue
的基本使用方法及注意事项。正确地使用这些容器适配器可以帮助你更有效地组织和管理数据。