1.队列
在 C++ 中,队列(Queue)是一种先进先出(FIFO,First In First Out)的数据结构,它是标准模板库(STL)中的一个适配器容器。队列适配器可以用不同的底层容器实现,但默认情况下,它通常是使用 std::deque
或 std::list
实现的。
基本特性和操作
队列主要支持以下几种操作:
- 入队(
push
):在队列的末尾添加一个元素。 - 出队(
pop
):移除队列的第一个元素。 - 访问队首元素(
front
):访问队列中的第一个元素,即队列中最早添加的元素。 - 访问队尾元素(
back
):访问队列中的最后一个元素,即队列中最后添加的元素(这在普通队列操作中不常用,但 C++ 的std::queue
提供了这个功能)。 - 检查是否为空(
empty
):检查队列是否为空。 - 获取大小(
size
):返回队列中的元素数量。
实现示例
下面是一个使用 C++ 的 std::queue
的简单示例:
#include <iostream>
#include <queue>
int main() {
std::queue<int> myQueue;
// 入队
myQueue.push(10);
myQueue.push(20);
myQueue.push(30);
// 访问队首和队尾元素
std::cout << "Front: " << myQueue.front() << std::endl; // 输出 10
std::cout << "Back: " << myQueue.back() << std::endl; // 输出 30
// 出队
myQueue.pop();
std::cout << "New Front: " << myQueue.front() << std::endl; // 输出 20
// 检查大小和是否为空
std::cout << "Queue size: " << myQueue.size() << std::endl; // 输出 2
std::cout << "Is empty: " << (myQueue.empty() ? "Yes" : "No") << std::endl; // 输出 No
return 0;
}
使用场景
队列在需要按顺序处理元素的场景中非常有用,如在任务调度、缓冲数据处理、实时计算等领域。通过限定数据的处理顺序,队列可以帮助维护数据的整合性和操作的可预测性。
注意事项
队列虽然是一个非常有用的数据结构,但它不支持随机访问,即不能直接访问队列中的任意位置的元素。如果需要这种操作,可能需要考虑使用其他类型的容器,如 std::vector
或 std::deque
。
2.栈
在 C++ 标准模板库(STL)中,栈(Stack)是一个容器适配器,具体是通过适配现有的序列容器(如 std::vector
, std::deque
, 或 std::list
)来提供一种后进先出(LIFO, Last In First Out)的数据结构。默认情况下,std::stack
使用 std::deque
作为其底层容器。
主要操作
std::stack
提供了一些基本操作来管理其元素集合,这些操作包括:
- push:向栈顶添加一个元素。
- pop:移除栈顶的元素,但不返回它。
- top:访问栈顶元素。
- empty:检查栈是否为空。
- size:返回栈中的元素数量。
这些操作确保了元素是按照后进先出的顺序进行管理的。
代码示例
下面的示例展示了如何在 C++ 中使用 std::stack
:
#include <iostream>
#include <stack>
int main() {
std::stack<int> s;
// 添加元素到栈
s.push(10);
s.push(20);
s.push(30);
// 显示栈顶元素
std::cout << "Top element: " << s.top() << std::endl; // 输出 30
// 移除栈顶元素
s.pop();
std::cout << "New top element after pop: " << s.top() << std::endl; // 输出 20
// 检查栈是否为空
std::cout << "Is stack empty? " << (s.empty() ? "Yes" : "No") << std::endl;
// 获取栈的大小
std::cout << "Stack size: " << s.size() << std::endl;
return 0;
}
选择底层容器
虽然默认情况下 std::stack
使用 std::deque
,但你可以选择其他容器作为其底层实现,例如 std::vector
或 std::list
。这是通过模板参数实现的,如:
std::stack<int, std::vector<int>> stackUsingVector;
std::stack<int, std::list<int>> stackUsingList;
选择不同的底层容器会影响程序的性能,特别是在频繁操作栈顶和栈大小变化时,不同容器的性能表现会有所不同。
使用场景
栈在许多算法和应用中都非常有用,特别是在需要反转元素顺序、实现递归算法的非递归版本、或者管理具有明确生命周期的对象时。例如,在解析表达式、回溯算法、深度优先搜索等场景中,栈都是一个理想的选择。