栈
栈是遵循后进先出 (LIFO) 原则的线性数据结构。元素从同一端(称为栈顶)添加和删除。可以想象成一摞盘子 - 只能从顶部添加或移除盘子。
栈在计算机科学中是基础性的,用于函数调用、表达式求值、撤销操作和许多算法中。
栈操作
栈的主要操作有:
- push(): 向栈顶添加元素
- pop(): 移除栈顶元素
- top()/peek(): 查看栈顶元素但不移除
- empty(): 检查栈是否为空
- size(): 获取元素数量
使用数组实现栈
#include <iostream>
using namespace std;
class Stack {
private:
int* arr;
int capacity;
int topIndex;
public:
Stack(int size) {
arr = new int[size];
capacity = size;
topIndex = -1;
}
~Stack() {
delete[] arr;
}
// Push element to top
void push(int value) {
if (topIndex >= capacity - 1) {
cout << "Stack Overflow! Cannot push " << value << endl;
return;
}
arr[++topIndex] = value;
cout << "Pushed: " << value << endl;
}
// Pop element from top
int pop() {
if (topIndex < 0) {
cout << "Stack Underflow! Cannot pop from empty stack" << endl;
return -1;
}
return arr[topIndex--];
}
// Peek at top element
int top() {
if (topIndex < 0) {
cout << "Stack is empty" << endl;
return -1;
}
return arr[topIndex];
}
// Check if stack is empty
bool empty() {
return topIndex < 0;
}
// Get size of stack
int size() {
return topIndex + 1;
}
// Display stack contents
void display() {
if (empty()) {
cout << "Stack is empty" << endl;
return;
}
cout << "Stack contents (top to bottom): ";
for (int i = topIndex; i >= 0; i--) {
cout << arr[i] << " ";
}
cout << endl;
}
};
int main() {
Stack stack(5);
// Push elements
stack.push(10);
stack.push(20);
stack.push(30);
stack.display();
cout << "Top element: " << stack.top() << endl;
cout << "Stack size: " << stack.size() << endl;
// Pop elements
cout << "Popped: " << stack.pop() << endl;
cout << "Popped: " << stack.pop() << endl;
stack.display();
// Try to pop from empty stack
stack.pop();
stack.pop(); // This will cause underflow
return 0;
}STL 栈
C++ 标准模板库提供了一个栈容器适配器,可以与不同的底层容器一起使用:
使用 STL 栈
#include <iostream>
#include <stack>
#include <vector>
#include <deque>
using namespace std;
int main() {
// Default stack (uses deque as underlying container)
stack<int> st;
// Push elements
st.push(10);
st.push(20);
st.push(30);
st.push(40);
cout << "Stack size: " << st.size() << endl;
cout << "Top element: " << st.top() << endl;
// Display and pop all elements
cout << "Stack contents: ";
while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;
// Stack with vector as underlying container
stack<int, vector<int>> stackWithVector;
stackWithVector.push(1);
stackWithVector.push(2);
stackWithVector.push(3);
cout << "Vector-based stack: ";
while (!stackWithVector.empty()) {
cout << stackWithVector.top() << " ";
stackWithVector.pop();
}
cout << endl;
// Stack of strings
stack<string> stringStack;
stringStack.push("First");
stringStack.push("Second");
stringStack.push("Third");
cout << "String stack: ";
while (!stringStack.empty()) {
cout << stringStack.top() << " ";
stringStack.pop();
}
cout << endl;
return 0;
}栈的应用
平衡括号检查
栈最常见的应用之一是检查表达式中的括号是否平衡:
平衡括号检查器
#include <iostream>
#include <stack>
#include <string>
using namespace std;
bool isBalanced(string expression) {
stack<char> s;
for (char ch : expression) {
// Push opening brackets
if (ch == '(' || ch == '[' || ch == '{') {
s.push(ch);
}
// Check closing brackets
else if (ch == ')' || ch == ']' || ch == '}') {
if (s.empty()) {
return false; // No matching opening bracket
}
char top = s.top();
s.pop();
// Check if brackets match
if ((ch == ')' && top != '(') ||
(ch == ']' && top != '[') ||
(ch == '}' && top != '{')) {
return false;
}
}
}
// Stack should be empty for balanced expression
return s.empty();
}
int main() {
vector<string> expressions = {
"()",
"()[]{}",
"([{}])",
"(((",
"())",
"([)]",
"{[()()]}"
};
cout << "Checking balanced parentheses:" << endl;
for (const string& expr : expressions) {
cout << expr << " -> "
<< (isBalanced(expr) ? "Balanced" : "Not Balanced")
<< endl;
}
return 0;
}表达式求值
栈可以用来求值后缀表达式(逆波兰表示法):
后缀表达式求值
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
using namespace std;
int evaluatePostfix(string expression) {
stack<int> s;
istringstream iss(expression);
string token;
while (iss >> token) {
if (token == "+" || token == "-" || token == "*" || token == "/") {
// Pop two operands
int operand2 = s.top(); s.pop();
int operand1 = s.top(); s.pop();
int result;
if (token == "+") result = operand1 + operand2;
else if (token == "-") result = operand1 - operand2;
else if (token == "*") result = operand1 * operand2;
else if (token == "/") result = operand1 / operand2;
s.push(result);
} else {
// Convert token to number and push
s.push(stoi(token));
}
}
return s.top();
}
int main() {
vector<string> expressions = {
"3 4 +", // 3 + 4 = 7
"5 2 * 3 +", // 5 * 2 + 3 = 13
"15 7 1 1 + - / 3 * 2 1 1 + + -", // Complex expression
"2 3 1 * + 9 -" // 2 + 3 * 1 - 9 = -4
};
cout << "Postfix Expression Evaluation:" << endl;
for (const string& expr : expressions) {
cout << expr << " = " << evaluatePostfix(expr) << endl;
}
return 0;
}