要弄明白什么是栈,就需要举一个生活化的例子。
假如有一个狭小的胡同,这个胡同一端开口,另一端封闭。有许多车在里面停着,这时往胡同里面停放车辆,先停的会靠近胡同内侧,后停车的会位于胡同入口。
【如图】
这时若想把靠后的车辆开出来,就需要先把最靠近入口的车开出来。即按照和停车顺序相反的顺序来取车。
【如图】
栈作为一种线性数据结构,特点为先入后出。最早进入的元素为栈底,最后进入的元素为栈顶。而由于是线性的,所以用数组和链表均可实现。
下面来讲栈的基本操作
1,入栈(push)
入栈操作就是把新元素放入栈中,只允许从栈顶一侧放入元素,新的元素会变为新的栈顶。
【如图】
2,出栈(pop)
出栈就是把栈顶从栈中弹出,而栈顶的后一位元素会随即变为新的栈顶。
【如图】
下列代码展示了c++中入栈和出栈的操作。 c++中提供了stack,使我们可以用它完成非常方便的操作(也是算法比赛必备知识了)
perl
#include <iostream>
#include <stack>
using namespace std;
int main() {
int size; // 定义一个整型变量,用于存储栈的大小
cout << "请输入栈的大小: "; // 提示用户输入栈的大小
cin >> size; // 从标准输入读取栈的大小
//下列框内代码可省略
////////////////////////////////////////////////////////////////////////////////////////////
if (size <= 0) { // 检查栈的大小是否为正数
cerr << "栈的大小必须为正数" << endl; // 如果栈的大小不是正数,输出错误信息
return 1; // 退出程序,返回错误码1
}
////////////////////////////////////////////////////////////////////////////////////////////
stack<char> charStack; // 定义一个字符栈
// 输入字符
cout << "请输入 " << size << " 个字符:\n"; // 提示用户输入指定数量的字符
for (int i = 0; i < size; ++i) { // 循环读取指定数量的字符
char c; // 定义一个字符变量
cin >> c; // 从标准输入读取一个字符
charStack.push(c); // 将读取的字符压入栈中
}
// 弹出并打印字符
cout << "从栈中弹出的字符为:\n"; // 提示用户即将输出从栈中弹出的字符
while (!charStack.empty()) { // 当栈不为空时,继续循环
cout << charStack.top() << ' '; // 输出栈顶的字符,并在字符后加一个空格
charStack.pop(); // 弹出栈顶的字符
}
cout << endl;
return 0;
}
另外,由于入栈和出栈只影响最后一个元素,时间复杂度均为O(1),是十分高效的操作。
同时由于它先入后出的特性,非常适合用于历史回溯的功能。