当前位置: 首页 > news >正文

数据结构:栈和队列(上)

汇总代码见:登录 - Gitee.com

上一篇文章:数据结构:双向链表-CSDN博客

与本文相关的结构体传参:自定义类型:结构体-CSDN博客

1.栈

1.1概念和结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶

栈底层结构选型:

栈的实现一般可以使用数组或者链表实现,相对而言,数组的结构实现更优一些。

原因:在入栈和出栈的时间复杂度均为O(1)的前提条件下,数组的内存利用率远高于链表,尤其是在存储小数据类型时。

1.2栈的实现

依旧建立三个文件:

1.2.1定义栈的结构


//定义栈的结构
typedef int STDataType;
typedef struct Stack {STDataType* arr;int top;//指向当前栈顶元素的索引--正好为栈中有效的数据个数int capacity;//栈的空间大小
}ST;

1.2.2初始化

//初始化
void STInit(ST* ps)
{ps->arr = NULL;ps->capacity = ps->size = 0;
}

调用调试:

1.2.3销毁

//销毁
void STDesTroy(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->size = ps->capacity = 0;
}

1.2.4入栈

// ⼊栈
void STPush(ST* ps, STDataType x)
{assert(ps);//判断空间是否足够if (ps->top == ps->capacity){//增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空间足够ps->arr[ps->top++] = x;
}

调用测试:

STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
STPush(&st, 5);

1.2.5判空

//栈是否为空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

1.2.6出栈

//出栈
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}

调用测试:

1.2.7取栈顶元素

top为指向当前栈顶元素的索引,所以需要-1。

//取栈顶元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}

调用测试:

while (!STEmpty(&st))
{//取栈顶STDataType top = STTop(&st);printf("%d ", top);//出栈STPop(&st);
}
printf("\n");

1.2.8获取栈中有效元素个数

//获取栈中有效元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}

调用测试:

printf("size:%d\n",STSize(&st));

1.3解释assert(ps)与assert(!STEmpty)

assert(ps):保证传入的为有效的栈结构体变量。限制参数不能为空。

assert(!STEmpty):保证栈中的有效个数不能为空。

2.力扣算法题:有效的括号

20. 有效的括号 - 力扣(LeetCode)

理解题意:

思路:借助栈,遍历字符串,如果遇到左括号,就将字符串入栈,如果遇到右括号,就取栈顶,将其与右括号相比较,相同则出栈。

编程中遇到的问题:有空字符串或者遇到一开始就是右括号的,需要判断栈是否为空以及对于条件表达式的使用错误。

代码如下:

// 需要借助栈
// 定义栈的结构
typedef char STDataType;
typedef struct Stack {STDataType* arr;int top;      // 指向当前栈顶元素的索引--正好为栈中有效的数据个数int capacity; // 栈的空间大小
} ST;
// 初始化
void STInit(ST* ps) {ps->arr = NULL;ps->capacity = ps->top = 0;
}// 销毁
void STDesTroy(ST* ps) {if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}// ⼊栈
void STPush(ST* ps, STDataType x) {assert(ps);// 判断空间是否足够if (ps->top == ps->capacity) {// 增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp =(STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL) {perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}// 空间足够ps->arr[ps->top++] = x;
}// 栈是否为空
bool STEmpty(ST* ps) {assert(ps);return ps->top == 0;
}// 出栈
void STPop(ST* ps) {assert(!STEmpty(ps));ps->top--;
}// 取栈顶元素
STDataType STTop(ST* ps) {assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}// 获取栈中有效元素个数
int STSize(ST* ps) {assert(ps);return ps->top;
}
// 以上为栈结构的定义与常见方法
bool isValid(char* s) {ST st;STInit(&st);char* i = s;while (*i != '\0') {// 左括号入栈if (*i == '(' || *i == '[' || *i == '{') {STPush(&st, *i);} else {// 右括号取栈顶,出栈或返回false// 若第一个为右括号,为空栈if (STEmpty(&st)) {STDesTroy(&st);return false;}char top = STTop(&st);if((top == '[' && *i != ']') || (top == '{' && *i != '}')|| (top == '(' && *i != ')')){STDesTroy(&st);return false;} //匹配-出栈STPop(&st);}i++;}// 栈是否为空//  if(STEmpty(&st))//  {//      STDesTroy(&st);//      return true;//  }// STDesTroy(&st);// return false;bool ret = STEmpty(&st) ? true : false;STDesTroy(&st);return ret;
}

最终通过测试。

本章完。


文章转载自:

http://l7d8v1IU.qxgmp.cn
http://WfF216yN.qxgmp.cn
http://SYFDiL4N.qxgmp.cn
http://ibwYraCp.qxgmp.cn
http://ex5XjeZK.qxgmp.cn
http://ehRnjGv2.qxgmp.cn
http://htkm1PfD.qxgmp.cn
http://bUJqBlYX.qxgmp.cn
http://3pggILEO.qxgmp.cn
http://Ae1kGR55.qxgmp.cn
http://Xd5Hc2RP.qxgmp.cn
http://7oJGOoNm.qxgmp.cn
http://vqjzA64H.qxgmp.cn
http://He0jLXqt.qxgmp.cn
http://46BT2PFB.qxgmp.cn
http://oTxHZbgY.qxgmp.cn
http://7URrHmA1.qxgmp.cn
http://UwNXihkd.qxgmp.cn
http://mCp9tQeB.qxgmp.cn
http://aVWwyCSa.qxgmp.cn
http://XGgaYaeD.qxgmp.cn
http://tWlUBp3j.qxgmp.cn
http://usMf1diA.qxgmp.cn
http://7Qu6W18r.qxgmp.cn
http://dv0FxUJP.qxgmp.cn
http://nf7sQv73.qxgmp.cn
http://NMJLzg6n.qxgmp.cn
http://TngplWBs.qxgmp.cn
http://uJf8GbNH.qxgmp.cn
http://9UlK2Jr1.qxgmp.cn
http://www.dtcms.com/a/365152.html

相关文章:

  • 低代码革命遇瓶颈?这个“套娃神技“才是破局关键!
  • 【FastDDS】Layer DDS之Domain ( 05-Creating a DomainParticipant)
  • 关于linux网络编程——3
  • 扫地日记:有鹿巡扫机器人在景区被人类“调戏”的365天
  • ansible总结2
  • GIS大学课程表都长啥样?几个地信专业的大学一周课程表
  • 如何评价2025年数学建模国赛?
  • (二)文件管理-基础命令-pwd命令的使用
  • 高并发数据写入场景下 MySQL 的性能瓶颈与替代方案
  • “我店”积分模式的可持续性拷问:短剧能否撑起长期消泡沫需求?
  • 蓝桥杯算法之基础知识(6)
  • Python函数和方法类型注释
  • k8s使用StatefulSet(有状态)部署单节点 MySQL方案(使用本地存储)
  • 【Python】 Python 项目初始化脚本
  • JavaWeb03
  • EagleTrader观察|你的固定心态,可能正在悄悄让你交易破产
  • 【踩坑记录】Unity 项目中 PlasticSCM 掩蔽列表引发的 文件缺失问题排查与解决
  • 3种通过USB从电脑传输文件到iPad的方法
  • Python_occ 学习记录 | 细观建模(1)
  • Ubuntu查看开机以来修改的文件
  • 论文介绍“DUSt3R”:让 3D 视觉从“繁琐”走向“直观”
  • 语音合成之二十六 TTS情感控制技术开源数据集
  • PHP如何解决使用国密SM4解密Base64数据错误问题?(基于lpilp/guomi)
  • [论文阅读] 人工智能 + 软件工程 | ReCode:解决LLM代码修复“贵又慢”!细粒度检索+真实基准让修复准确率飙升
  • 一键 i18n 国际化神库!适配 Vue、React!
  • CMake构建学习笔记24-使用通用脚本构建PROJ和GEOS
  • Web端最强中继器表格元件库来了!55页高保真交互案例,Axure 9/10/11通用
  • Java学习笔记-零基础学MySQL(四)
  • 三阶Bezier曲线,已知曲线上一点到曲线起点的距离为L,计算这个点的参数u的方法
  • 【C++】C++入门—(中)