数据结构基础 - 栈与队列
栈和队列有哪些特殊的操作?栈和队列能解决什么样的问题?用栈和队列这种数据结构,来解决与“先进先出”、“先进后出”有关的实际问题了,如宽度优先搜索、表达式求值等。 类比 - 日常生活普遍规律 如果桌上有一叠盘子,大家都只会拿最上面的那一个。食堂排队的时候,你总是先找到队尾加入,而排在队首的同学打完饭之后就会离开。 类比计算机,也许只需要在线性序列的一端或两端进行操作,对应的就是栈和队列这两种受限的线性表,他们是最简单的基础数据结构,应用也最广泛。 重点:栈的 LIFO(后进先出) 特性,深度优先搜索,理解递归中栈的作用;队列的 FIFO(先进先出)特性,宽度优先搜索。 难点:机械的递归转非递归,简单理解就可以了,不需要掌握;顺序队列的实现假溢出处理。 栈 在C++程序中,栈(Stack) 是一种非常重要的线性数据结构,它遵循 LIFO(Last In, First Out) 原则,即 后进先出。 一、栈的核心特点 后进先出(LIFO):最后被添加到栈中的元素,会最先被移除。 只能在一端操作:所有的插入(入栈/Push)和删除(出栈/Pop)操作都发生在栈的同一端,这一端被称为 栈顶(Top)。 另一端是固定的:栈的另一端称为 栈底(Bottom)。 📌 类比: 想象一个放羽毛球的筒: 你只能从筒的开口(栈顶)放入或取出羽毛球。 最后放进去的球,会最先被拿出来。 二、栈的基本操作 操作 描述 push(x) 将元素 x 压入栈顶 pop() 移除并返回栈顶元素 top() / peek() 返回栈顶元素,但不移除 empty() 判断栈是否为空 size() 返回栈中元素的个数 三、C++ 中如何实现栈? C++ 提供了两种主要方式来使用栈: 1. 使用 STL 容器适配器 std::stack 这是最常用、最推荐的方式。std::stack 是一个容器适配器,默认基于 std::deque 实现。 #include <iostream> #include <stack> int main() { std::stack<int> s; // 创建一个存储 int 类型的栈 s.push(10); // 入栈 s.push(20); s.push(30); std::cout << "栈顶元素: " << s.top() << std::endl; // 输出: 30 s.pop(); // 出栈 std::cout << "新的栈顶元素: " << s.top() << std::endl; // 输出: 20 std::cout << "栈的大小: " << s.size() << std::endl; // 输出: 2 if (!s.empty()) { std::cout << "栈非空" << std::endl; } return 0; } std::stack 的特点: 使用简单,接口清晰。 默认底层容器是 std::deque,也可以指定为 std::vector 或 std::list: std::stack<int, std::vector<int>> s_vec; // 基于 vector std::stack<int, std::list<int>> s_list; // 基于 list 2. 自己用数组或链表实现 虽然不常用,但理解其原理很重要。 ...