数据结构——栈
什么是栈
栈(Stack)又称为堆栈,是一种受限制的线性表只允许从一端插入和删除数据。因为栈的插入和删除只能在栈顶进行,所以每次删除的元素都是栈中的最后一个元素,故栈的特征是先进后出。
当我们了解了栈是定义和性质之后,我们就可以自己手写一个栈,我们可以用定义长度为\(N\)的数组\(S\)来表示,用一个栈指针\(top\)指向栈顶,若\(top=0\),表示栈空,\(top=N\)时,表示栈满。进栈时\(top++\),出栈时\(top--\)。当\(top<0\)时,表示下溢。栈指针在运算过程中永远指向栈顶。
栈的相关概念
- 栈顶与栈底:允许元素插入与删除的一端称之为栈顶,另一端称之为栈底
- 压栈:栈的插入操作称之为进栈,也称之为压栈,入栈
- 弹栈:栈的删除操作称之为出栈
栈的基本操作:
- 弹栈:通常名为\(pop\);
- 压栈:通常名为\(push\);
- 求栈的大小
- 判断栈是否为空
- 获取栈顶元素的值
栈的常见分类
- 基于数组的栈——以数组为底层数据结构时,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向。
- 基于单链表的栈——以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部
实战操作
- 使用STL的栈时,应包含相关头文件,栈的头文件:\(\#include <stack>\)。定义栈,方式如下:\(stack<type>s\);type为数据类型
s.push(itme); //把itme放入栈内
s.pop(); //删除栈顶元素,但不出栈
s.top(); //返回栈顶元素,但不出栈
s.size(); //返回栈中元素个数
s.empty(); //检查栈是否为空,空返回true,反之返回false
#include <iostream>
#include <stack> //栈的头文件
using namespace std;
#define endl '\n'
int main(){
stack<int>st; //定义一个整型栈
for(int i = 1; i <= 10; i++){
st.push(i); // 将元素压栈
}
cout << "the size of the stack is " << st.size() << endl; //判断栈的大小
while(!st.empty()){ //判断栈是否为空
cout << st.top() << " "; //返回栈顶元素的数值
st.pop(); // 弹出栈顶元素
}
system("pause");
return 0;
}
//the size of the stack is 10
//10 9 8 7 6 5 4 3 2 1
- 基于数组的栈
#include <iostream>
#include <stack>
using namespace std;
#define endl '\n'
int st[100];//用数组存储
int top = 1;//指针始终指向栈顶
int main(){
for(int i = 1; i <= 10; i++){
st[top++] = i;
}
cout << "the size of the stack is " << top - 1 << endl;
while(top != 1){
cout << st[--top] << " ";
}
return 0;
}
//the size of the stack is 10
//10 9 8 7 6 5 4 3 2 1
- 基于单链表的栈
#include <iostream>
using namespace std;
template<class T>class stack{
private:
struct Node{
T data;
Node *next;
};
Node *head;
Node * p;
int length;
public:
stack(){
head = NULL;
length = 0;
}
void push(T n){
Node * q = new Node;
q->data = n;
if(head == NULL){
q->next = head;
head = q;
p = q;
}
else{
q->next = p;
p = q;
}
length++;
}
T pop(){
if(length <= 0){
abort(); // 中止程序执行,直接从调用的地方跳出
}
Node *q;
T data;
q = p;
data = p->data;
p = p->next;
delete q;
length--;
return data;
}
int size(){
return length;
}
T top(){
return p->data;
}
bool empty(){
if(length == 0) return true;
else return false;
}
void clear(){
if(length > 0) pop();
}
};
int main(){
stack<int>st; //定义一个整型栈
for(int i = 1; i <= 10; i++){
st.push(i); // 将元素压栈
}
cout << "the size of the stack is " << st.size() << endl; //判断栈的大小
while(!st.empty()){ //判断栈是否为空
cout << st.top() << " "; //返回栈顶元素的数值
st.pop(); // 弹出栈顶元素
}
system("pause");
return 0;
}
//the size of the stack is 10
//10 9 8 7 6 5 4 3 2 1
栈的应用
- 进制转换
- 括号匹配的检验
- 行编辑程序
- 迷宫求解、含诺诺等经典为题
- 表达式求值
- 栈与递归的实现