🎁个人主页:工藤新一¹
🔍系列专栏:C++面向对象(类和对象篇)
🌟心中的天空之城,终会照亮我前方的路
🎉欢迎大家点赞👍评论📝收藏⭐文章
文章目录
栈
一、栈的概念
1.1概念与结构
栈:是一种只允许在固定的一段 (栈顶)进行插入和删除元素操作的线性表(访问受限的线性表,任何操作都必须在线性表的最后(栈顶)面执行)。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵循着后进先出**LIFO(Last In First Out)**的原则。
**压栈:**栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
**出栈:**栈的删除操作叫做出栈,出数据也在栈顶
- 逻辑结构上:线性的
- 物理结构上:数组实现的栈是线性的,由链表实现的栈一般是非线性的
二、数组实现栈
2.1栈的定义与初始化
C
//定义栈数据
typedef int STDataType;
typedef struct Stack
{
STDataType* arr;
int top;//有效元素个数(指向栈顶位置)
int capacity;//栈的容量
}ST;
//为栈中数据进行初始化
void StackInit(ST* ps)
{
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
2.2入栈、出栈
- Stack.h
C
//入栈
void StackPush(ST* ps, STDataType x);
//出栈
void StackPop(ST* ps)
- Stack.cpp
C
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
//增容,if(ps->capacity == 0)向内存申请 4 个 STDataType 类型的空间
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* temp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (temp == NULL)
{
perror("realloc fail!");
exit(1);
}
ps->arr = temp;
ps->capacity = newCapacity;
}
ps->arr[ps->top++] = x;
}
//判空操作
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;//为空,返回true
}
void StackPop(ST* ps)
{
//assert(!true) - false 终止代码运行
assert(!StackEmpty(ps));//保证 ps 不为空,才能执行以下操作
/*
断言:
条件为true,程序继续执行
条件为false,程序会终止
*/
ps->top--;
}
2.3出栈顶数据、获取栈中有效元素个数
- Stack.h
C
//出栈顶数据
STDataType StackTop(ST* ps);
//获取栈中有效元素个数
int StackSize(ST* ps);
- Stack.cpp
C
STDataType StackTop(ST* ps)
{
assert(!StackEmpty(ps));
return ps->arr[ps->top - 1];
}
int StackSize(ST* ps)
{
return ps->top;
}
2.4销毁栈
- Stack.h
C
//销毁栈
void StackDestroy(ST* ps);
- Stack.cpp
C
void StackDestroy(ST* ps)
{
if (ps->arr)
free(ps->arr);
ps->arr = NULL;
ps->capacity = ps->capacity == 0;
}
三、数据删除 ---- 对顺序表、链表的理解
删除数据不需要 free 吗 ?
在先前讲解链表时,我们每删除一个节点,就会 free
回收掉该节点,那为什栈中不执行这样的操作呢? (而是,ps->top–)
-
因为栈的底层是一个数组(数组的存储空间是连续的),如果
free(arr)
那么就会将以 ps->arr 为起始地址后的所有数据全部释放掉 -
为什么在链表中可以一个一个的销毁呢?
-
因为链表的存储结构是由一个个相互独立的节点组成的,
free
掉其中一个节点,并不会影响其他节点
四、栈代码
- Stack.h
C
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<iostream>
using namespace std;
typedef int STDataType;
typedef struct Stack
{
STDataType* arr;
int top;//有效元素个数(指向栈顶位置)
int capacity;//栈的容量
}ST;
//使形参可以影响实参 - 地址传递 - 指针接收
void StackInit(ST* ps);
//入栈
void StackPush(ST* ps, STDataType x);
//出栈
void StackPop(ST* ps);
//判空 - 栈是否为空
bool StackEmpty(ST* ps);
//出栈顶数据
STDataType StackTop(ST* ps);
//获取栈中有效元素个数
int StackSize(ST* ps);
//销毁栈
void StackDestroy(ST* ps);
- test.c
C
#include"Stack.h"
void test01()
{
ST st;
StackInit(&st);
StackPush(&st, 10);
StackPush(&st, 20);
StackPush(&st, 30);
StackPush(&st, 40);
StackPush(&st, 50);
StackPop(&st);
//StackPop(&st);
//StackPop(&st);
//StackPop(&st);
//StackPop(&st);
//while(!StackEmpty(&st))//如果栈不为空
//{
//int top = StackTop(&st);
//printf("%d ", top);
//StackPop(&st);
//}
int size = StackSize(&st);
printf("%d\n", size);//栈中有效元素个数
StackDestroy(&st);
string s;
isValid(s);
}
int main()
{
test01();
return 0;
}
- Stack.cpp
C
#include"Stack.h"
void StackInit(ST* ps)
{
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
//增容,if(ps->capacity == 0)向内存申请 4 个 STDataType 类型的空间
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* temp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (temp == NULL)
{
perror("realloc fail!");
exit(1);
}
ps->arr = temp;
ps->capacity = newCapacity;
}
ps->arr[ps->top++] = x;
}
//判空操作
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;//为空,返回true
}
void StackPop(ST* ps)
{
//assert(!true) - false 终止代码运行
assert(!StackEmpty(ps));//保证 ps 不为空,才能执行以下操作
/*
断言:
条件为true,程序继续执行
条件为false,程序会终止
*/
ps->top--;
}
STDataType StackTop(ST* ps)
{
assert(!StackEmpty(ps));
return ps->arr[ps->top - 1];
}
int StackSize(ST* ps)
{
return ps->top;
}
void StackDestroy(ST* ps)
{
if (ps->arr)
free(ps->arr);
ps->arr = NULL;
ps->capacity = ps->capacity == 0;
}
- OJ - 有效括号
C
typedef char STDataType;
bool isValid(char* s)
{
ST st;
StackInit(&st);
char* pi = s;
while (pi != '\0')
{
if (*pi == '(' || *pi == '[' || *pi == '{')
{
StackPush(&st, *pi);
}
else
{
if (StackEmpty(&st)) return false;
if ((*pi == ')' && StackTop(&st) != '(')
|| (*pi == ']' && StackTop(&st) != '[')
|| (*pi == '}' && StackTop(&st) != '{'))
{
StackDestroy(&st);
return false;
}
StackPop(&st);
}
pi++;
}
bool ret = StackEmpty(&st) ? true : false;
StackDestroy(&st);
return ret;
}
🌟 各位看官好,我是工藤新一¹呀~
🌈 愿各位心中所想,终有所致!