数据结构✈️栈
文章目录
- 数据结构✈️栈
- 一、🚀什么是栈?
- 二、🛸栈的实现
- 1、使用类实现
- 2、使用数组实现
- 3、使用链表实现
一、🚀什么是栈?
栈(Stack)是一种抽象数据类型(ADT),它是一种特殊的线性数据结构,具有后进先出
(Last In First Out, LIFO
)的行为特征。这意味着最后一个进入栈的元素将是第一个被取出的元素。
top(栈顶)
:栈中最后一个被加入的元素所在的顶部位置。Push(压栈)
:将一个元素添加到栈顶。Pop(出栈)
:从栈顶移除一个元素。空栈
:当栈中没有任何元素时,称为空栈。
二、🛸栈的实现
1、使用类实现
使用类实现比较简单,就和正常写一个类一样,这里我直接放代码。
#include<iostream>
using namespace std;
class Stack{
private:
int* data; // 指向数组的指针
size_t capacity; // 栈的最大容量
int top; // 栈顶元素的索引
public:
Stack(size_t capacity = 10) : capacity(capacity), top(-1) {
data = new int[capacity];
}
~Stack() {
delete[] data;
}
void push(int value) {
if (top + 1 >= capacity) {
cout<< "Stack overflow."<<endl;//抛出异常
}
data[++top] = value;
}
int pop() {
if (top < 0) {
cout<< "Stack underflow."<<endl;
}
return data[top--];
}
int peek() const {//返回栈顶的元素
if (top < 0) {
cout<<"Stack is empty."<<endl;
}
return data[top];
}
bool is_empty() const {//判断栈是否为空
return top < 0;
}
void print_stack() const {
if (is_empty()) {
cout << "The stack is empty." <<endl;
return;
}
cout << "Stack contents:"; //如果栈不是空的就从最底部开始循环打印
for (int i = 0; i <= top; i++){
cout << data[i] << " ";
}
}
};
构造函数 (Stack(size_t capacity))
: 初始化栈的大小为默认值或传入的值,并分配内存。析构函数 (~Stack())
: 释放分配给栈的内存。push()
: 向栈中添加一个元素。如果栈已满,则抛出异常。pop()
: 从栈顶移除并返回一个元素。如果栈为空,则抛出异常。peek()
: 返回栈顶元素但不移除它。如果栈为空,则抛出异常。is_empty()
: 判断栈是否为空。print_stack()
:从栈底开始打印
2、使用数组实现
使用数组实现时先定义一个数组A
和top
,因为数组的索引是从0开始,所以开始要将top
赋值为-1,这样在Push
数据时top
就会+1,此时栈顶top
就和数组索引一样。
#include<iostream>
#define MAX_SIZE 101 //定义一个宏
using namespace std;
int A[MAX_SIZE];//使用数组实现栈
int top = -1;// 空栈
void Push(int x){
if(top == MAX_SIZE-1){ //判断栈是否满员
cout<<"Error:stack overflow\n";
return;
}
A[++top] = x;
}
void Pop(){
if(top == -1){
cout<<"Error:No element to pop \n";
return;
}
top--;
}
void Peek(){
if(top == -1){
cout<<"Error:No element to peek \n";
return;
}
cout<<"The top element is "<<A[top]<<"\n";
}
void is_empty(){
if(top == -1){
cout<<"The stack is empty\n";
return;
}
cout<<"The stack is not empty\n";
}
void Print(){
int i;
cout<<"Stack:";
for(i=0;i<=top;i++) {
cout << A[i]<<" ";
}
cout<<"\n";
}
3、使用链表实现
前面提到使用类实现或者数组实现栈时都存在一个共同的问题,就是栈的大小要提前定义好,一旦数据过多超出栈的容量,就会出现栈溢出的情况。如果你学过链表的话,根据链表动态分配内存的特点就可以完美解决数据溢出的问题。没学过链表的可以先看看这篇数据结构之链表(看不懂你来找我)。
struct Node{
int data;
struct Node* next;
};
struct Node* top = NULL;
void Push(int x){
struct Node* temp = new Node();
temp->data = x;
temp->next = top;
top = temp;
}
void Pop(){
struct Node* temp;
if(top == NULL){
cout<<"Stack Underflow\n";
return;
}
temp = top;
top = top->next;
free(temp);
}
void Top(){
if(top == NULL){
cout<<"Stack is empty\n";
return;
}
cout<<"Top element is "<<top->data<<"\n";
}
void Is_empty(){
if(top == NULL){
cout<<"Stack is empty\n";
return;
}
cout<<"Stack is not empty\n";
}
这里给大家画个图解(以Push
函数为例)