栈、队列与数组的对比与复习要点
栈(Stack)
栈是一种后进先出(LIFO)的线性结构,仅允许在栈顶进行插入(push)和删除(pop)操作。
核心操作:
push(x):将元素x压入栈顶。pop():弹出栈顶元素。peek():获取栈顶元素但不删除。isEmpty():判断栈是否为空。
应用场景:
- 函数调用栈(递归实现)。
- 表达式求值(如括号匹配、中缀转后缀)。
- 浏览器的前进后退功能。
实现方式:
- 数组实现:需预先分配固定大小,通过指针(如
top)跟踪栈顶位置。 - 链表实现:动态分配内存,灵活性更高。
考研常见考点:
- 栈的出入序列合法性(如给定入栈序列,判断某出栈序列是否可行)。
- 双栈共享空间的设计(如两个栈共享一个数组)。
队列(Queue)
队列是一种先进先出(FIFO)的线性结构,插入在队尾(rear),删除在队头(front)。
核心操作:
enqueue(x):将x插入队尾。dequeue():删除队头元素。front():获取队头元素。isEmpty():判断队列是否为空。
特殊队列:
- 循环队列 :解决数组实现的假溢出问题,通过模运算实现环形结构。
- 判空:
front == rear。 - 判满:
(rear + 1) % size == front。
- 判空:
- 双端队列(Deque):两端均可插入和删除。
- 优先队列:元素按优先级出队,通常用堆实现。
应用场景:
- 任务调度(如CPU任务队列)。
- 广度优先搜索(BFS)中的辅助数据结构。
考研常见考点:
- 循环队列的判空与判满条件。
- 队列的链式实现(带头结点/不带头结点)。
数组(Array)
数组是连续内存存储的线性结构,支持随机访问(时间复杂度O(1))。
核心特性:
- 静态性:长度固定(动态数组如C++的
vector可扩容,但需重新分配内存)。 - 多维数组:如二维数组的行优先/列优先存储方式。
与栈/队列的区别:
- 栈和队列是逻辑结构,可用数组或链表实现;数组是物理存储结构。
- 数组的插入/删除效率低(需移动元素),而栈/队列的插入删除严格受限。
考研常见考点:
- 数组的地址计算(如二维数组
a[m][n]中a[i][j]的地址)。 - 稀疏矩阵的压缩存储(三元组表、十字链表)。
复习建议
- 对比记忆:总结三者的操作限制(如栈仅一端操作,队列两端操作但受限)。
- 代码实现:手写栈/队列的数组和链表实现,注意边界条件(如栈满/空)。
- 真题演练:重点练习出入序列合法性、循环队列判满等高频题型。
- 复杂度分析:明确栈/队列的插入删除均为O(1),数组插入删除为O(n)。
示例代码(C++)
cpp
// 栈的数组实现
class Stack {
int top, capacity;
int* arr;
public:
Stack(int size) : capacity(size), top(-1) { arr = new int[size]; }
void push(int x) { if (top < capacity - 1) arr[++top] = x; }
int pop() { if (!isEmpty()) return arr[top--]; return -1; }
bool isEmpty() { return top == -1; }
};
// 循环队列实现
class CircularQueue {
int front, rear, size;
int* arr;
public:
CircularQueue(int k) : size(k + 1), front(0), rear(0) { arr = new int[k + 1]; }
bool enQueue(int x) {
if (isFull()) return false;
arr[rear] = x;
rear = (rear + 1) % size;
return true;
}
bool isFull() { return (rear + 1) % size == front; }
};