数据结构——栈和队列(C语言)

栈种常见的数据结构,它用来解决一些数据类型的问题,那么好,我来带着大家来学习一下栈

文章目录

    • 对栈的认识
    • 栈的模拟实现
    • 栈的练习
      • 方法一
      • 方法二

对栈的认识

栈(stack)是限定只能在表的一端进行插入删除操作的线性表

栈是一种先进后出的顺序结构,这里的先进后出就是先进来的数据要后出(跟没说一样)
就是1,2,3,4,5这五个数据,只能从5到1逐个访问。

数据结构栈的定义

栈顶:栈顶元素,最后一个入栈的元素
入栈
出栈
栈空:判断栈是否为空
栈的大小:返回站内元素个数

栈的模拟实现

在了解了栈之后,我们来对它进行简单的实现一下。
首先,我们应该先了解大框架,这里我们用数组的方式进行模拟实现(比较合适的方式,其他的也可以)

我们采用分模块的方式进行实现,这里,我在代码中会进行注释,可直接阅读代码来学习栈的实现。

stack.h用来声明各种头文件。
stack.c用来实现各个功能的实现包括入栈。 出栈等栈的基本功能。
test.h来测试代码功能

stack.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//栈可以村粗不同类型的数据,这里我们直接使用·typedef重定义类型
typedef int stdatetype;//用结构体来实现栈
typedef struct stack {int capacity;//capacity表示栈的容量int top;//栈顶元素int* a;//数组
}st;//st是重命名的结果//栈的初始化
void initst(st* pst);//栈的插入和删除
void pushback(st* pst,stdatetype x);void popback(st* pst);
void printst(st* pst);//返回栈顶元素
stdatetype sttop(st* pst);//返回栈内元素个数
int sizest(st* pst);//返回栈是否为空
bool empty(st* pst);//销毁栈
void destroy(st* pst);

stack.c

#include"stack.h"//初始化栈
void initst(st* pst)
{pst->top = -1;//top初始化为-1(这里也可以是零,但下面的代码也需要改动)//栈的容量pst->capacity = 0;//capacity可扩容pst->a = NULL;//对数组a进行制空
}//入栈
void pushback(st* pst,stdatetype x)
{assert(pst);//断言,以防止pst是一个空指针if ((pst->top + 1) == pst->capacity)//判断,如果top+1等于栈的容量的话,就要进行扩容{pst->capacity = pst->capacity == 0 ? 4 : pst->capacity * 2;stdatetype* tail = (stdatetype*)realloc(pst->a, sizeof(stdatetype)*pst->capacity);assert(tail);//断言一下,如果扩容失败,终止程序pst->a = tail;//扩容成功,把地址给a}pst->a[++(pst->top)] = x;//入栈
}//出栈
void popback(st* pst)
{assert(pst);//如果栈为空,终止程序assert(pst->top > -1);pst->top--;
}//返回栈顶元素
stdatetype sttop(st* pst)
{assert(pst);//栈为空终止程序assert(pst->top > -1);return pst->a[pst->top];//返回栈顶元素
}//返回栈的大小
int sizest(st* pst)
{assert(pst);return pst->top + 1;
}//判断栈是否为空
bool empty(st* pst)
{assert(pst);return pst->top == -1;//直接进行判断
}//销毁栈
void destroy(st* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = -1;pst->capacity = 0;}

test.c

#include"stack.h"int main()
{st s;initst(&s);pushback(&s, 1);pushback(&s, 2);pushback(&s, 3);printf("%d", sizest(&s));popback(&s);while (s.top > -1)printf("%d--", s.a[s.top--]);//因为栈的特点,要这样对栈进行打印if (empty(&s))printf("\n空");destroy(&s);return 0;
}

好了,栈是比较简单的数据结构,学习到这里,相信你也已经对栈有了一定的了解,

栈的练习

下面我们来做一道题,趁热打铁一下
https://leetcode.cn/problems/valid-parentheses/description/

在这里插入图片描述
这是这道题的要求
在这里插入图片描述

这道题就非常适合使用栈来解决,当我们学完C++之后,stl库的使用会让我们更轻松的解决这道题,但是我们这里也有解决方法,我们可以直接把上面的模拟实现,稍做修改拿来使用

这里我·提供两种方法(都可以通过)

方法一

下面是这道题的代码,大部分都是在实现栈,当我们学习过C++stl之后,这就会非常简单

bool isValid(char* s) {#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef char stdatetype;//用结构体来实现栈
typedef struct stack {int capacity;//capacity表示栈的容量int top;//栈顶元素stdatetype* a;//数组
}st;//st是重命名的结果void initst(st* pst)
{pst->top = -1;//top初始化为-1(这里也可以是零,但下面的代码也需要改动)//栈的容量pst->capacity = 0;//capacity可扩容pst->a = NULL;//对数组a进行制空
}//入栈
void pushback(st* pst,stdatetype x)
{assert(pst);//断言,以防止pst是一个空指针if ((pst->top + 1) == pst->capacity)//判断,如果top+1等于栈的容量的//话,就要进行扩容{int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;stdatetype* tail = (stdatetype*)realloc(pst->a, sizeof(stdatetype)*newcapacity);assert(tail);//断言一下,如果扩容失败,终止程序pst->a = tail;//扩容成功,把地址给apst->capacity=newcapacity;}pst->a[++(pst->top)] = x;//入栈
}//出栈
void popback(st* pst)
{assert(pst);//如果栈为空,终止程序assert(pst->top > -1);pst->top--;
}//返回栈顶元素
stdatetype sttop(st* pst)
{assert(pst);//栈为空终止程序assert(pst->top > -1);return pst->a[pst->top];//返回栈顶元素
}//返回栈的大小
int sizest(st* pst)
{assert(pst);return pst->top + 1;
}//判断栈是否为空
bool empty(st* pst)
{assert(pst);return pst->top == -1;//直接进行判断
}//销毁栈
void destroy(st* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = -1;pst->capacity = 0;}st _st;initst(&_st);while(*s){char ch=*s;if(ch=='{'||ch=='('||ch=='['){pushback(&_st,ch);}else{if(_st.top==-1){destroy(&_st);//防止内存泄露return false;}if((ch=='}'&&sttop(&_st)!='{')||(ch==')'&&sttop(&_st)!='(')||(ch==']'&&sttop(&_st)!='[')){destroy(&_st);return false;}popback(&_st);}s++;}if(!empty(&_st)){destroy(&_st);return false;}destroy(&_st);return true;
}

方法二

这样的实现过于麻烦,我们也有另一种方法,用数组快速的模拟栈
直接看代码吧

bool isValid(char* s) {const int N = 10010;int st[N];int hh=0;while(*s){char top=*s;if(top=='{'||top=='('||top=='['){st[hh++]=top;}else{if(hh==0)return false;if((top=='}'&&st[hh-1]!='{')||(top==')'&&st[hh-1]!='(')||(top==']'&&st[hh-1]!='[')){return false;}hh--;}s++;}if(hh){return false;}return true;
}

栈的学习就先到这里了,各位有什么不同见解可以说出来,一起交流一下

感谢观看,有错误请指出

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/441278.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VxTerm:SSH工具中的中文显示和乱码时的相关信息和一些基本的知识

当我们写的程序含有控制台(Console)输出时&#xff0c;如果输入内容包含中文时&#xff0c;我们一般需要知道下面的信息&#xff0c;才能正确的搞清楚怎么处理中文显示的问题&#xff1a; 1、实际程序或文件中的实际编码&#xff1a; Linux下的应用程序和文本文件&#xff0c;…

系统架构设计师-21年-下午题目

系统架构设计师-21年-下午题目 更多软考知识请访问 https://ruankao.blog.csdn.net/ 试题一必答&#xff0c;二、三、四、五题中任选两题作答 试题一 (25分) 说明 某公司拟开发一套机器学习应用开发平台&#xff0c;支持用户使用浏览器在线进行基于机器学习的智能应用开发…

matlab appdesigner系列-仪器仪表3-旋钮

旋钮&#xff0c;同过旋转显示特定的值 示例&#xff1a;模拟收音机调频 操作步骤&#xff1a; 1&#xff09;将旋钮、标签按钮拖拽到画布上&#xff0c;将标签文字修改为&#xff1a;欢迎收听&#xff0c;并将旋钮其数值范围改为90-107 2&#xff09;设置旋钮的回调函数 代…

15EG使用vivado2023.1建立hello world工程

1:打开软件建立工程 2:使用vivado创建设计模块并生成bit文件 3:导出硬件平台&#xff0c;使用vitis建立工程 4:使用vitis创建应用程序项目 5:硬件设置与调试 1:打开软件建立工程 打开VIVADO2023.1 创建一个新的工程 输入项目名称和地址&#xff0c;下面那个选项为是否…

力扣日记1.30【回溯算法篇】78. 子集

力扣日记&#xff1a;【回溯算法篇】78. 子集 日期&#xff1a;2023.1.30 参考&#xff1a;代码随想录、力扣 78. 子集 题目描述 难度&#xff1a;中等 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 …

CCF-CSP 202312-2 因子化简(Java、C++、Python)

文章目录 因子化简题目背景问题描述输入格式输出格式样例输入样例输出样例解释子任务 满分代码JavaCPython线性筛法 因子化简 题目背景 质数&#xff08;又称“素数”&#xff09;是指在大于 1 的自然数中&#xff0c;除了 1 和它本身以外不再有其他因数的自然数。 问题描述…

现货白银的交易策略包括哪些内容?如何适应策略?

交易策略被投资者视为做现货白银交易通向盈利之路的必备工具&#xff0c;但是投资者却不知道如何建立一个适合自己的交易策略&#xff0c;如果直接拿别人的交易策略过来&#xff0c;就犯了拿来主义的毛病&#xff0c;这样是不行的&#xff0c;下面我们就来简单讨论一下如何建立…

Linux操作系统概述

操作系统&#xff08;Operating System&#xff09;的定义 操作系统&#xff0c;是指直接管理系统硬件和资源&#xff08;如 CPU、内存和存储空间&#xff09;的软件。 操作系统的基本功能 ①统一管理计算机资源&#xff1a;处理器资源&#xff0c;IO设备资源&#xff0c;存储…

使用AXI GPIO IP核点亮led

本例程使用SD卡启动模式 创建工程模板在hello_world中已经介绍过了&#xff0c;这里直接从配置完zynq ip核开始 点击加号&#xff0c;搜索GPIO&#xff0c;双击添加AXI GPIO IP核 双击 GPIO IP 核进行设置&#xff0c;设置为输出模式&#xff0c;位宽为4&#xff0c;设置完成后…

超过1000种工具揭示了单细胞RNA数据分析的趋势

文章&#xff1a;Over 1000 tools reveal trends in the single-cell RNA-seq analysis landscape 杂志&#xff1a;Genome Biology 年份&#xff1a;2021 从 2016 年开始&#xff0c;scRNA-tools 数据库&#xff08;https://www.scrna-tools.org/&#xff09;不断收集单细胞转…

el-input 显示最大长度和已输入内容长度

效果如下图 多行文本框&#xff1a; 单行文本框&#xff1a; 需要设置 maxlength 和 show-word-limit 两个属性&#xff0c;在使用 maxlength 属性限制最大输入长度的同时&#xff0c;可通过设置 show-word-limit 属性来展示字数统计。 <el-inputtype"textarea&quo…

ElasticSearch面试题整理(持续更新)

1. Elasticsearch 中的倒排索引是什么&#xff1f; Elasticsearch 使用一种称为倒排索引的结构&#xff0c;ES中的倒排索引其实就是 lucene 的倒排索引&#xff0c;区别于传统的正向索引&#xff0c;倒排索引会再存储数据时将关键词和数据进行关联&#xff0c;保存到倒排表中&…

医院如何筛选安全合规的内外网文件交换系统?

医院内外网文件交换系统是专为医疗机构设计的&#xff0c;用于在内部网络&#xff08;内网&#xff09;和外部网络&#xff08;外网&#xff09;之间安全、高效地传输敏感医疗数据和文件的解决方案。这种系统对于保护患者隐私、遵守医疗数据保护法规以及确保医疗服务的连续性和…

Angular组件(二) 分割面板ShrinkSplitter

Angular组件(二) 分割面板ShrinkSplitter 前言 在Angular组件(一) 分割面板ShrinkSplitter文章中我们实现了Splitter组件&#xff0c;后来在业务场景中发现在开关右侧容器和底部容器时&#xff0c;使用起来不方便&#xff0c;ngModel绑定的值始终是左侧容器和顶部容器的大小&…

顺序表的奥秘:高效数据存储与检索

&#x1f37f;顺序表 &#x1f9c0;1、顺序表的实现&#x1f365;1.1 创建顺序表类&#x1f365;1.2 插入操作&#x1f365;1.3 查找操作&#x1f365;1.4 删除操作&#x1f365;1.5 清空操作 &#x1f9c0;2、ArrayList的说明&#x1f9c0;3、ArrayList使用&#x1f365;3.1 A…

网络安全全栈培训笔记(59-服务攻防-中间件安全CVE复现lSApacheTomcataNginx)

第59天 服务攻防-中间件安全&CVE复现&lS&Apache&Tomcata&Nginx 知识点&#xff1a; 中间件及框架列表&#xff1a; lIS,Apache,Nginx,Tomcat,Docker,Weblogic,JBoos,WebSphere,Jenkins, GlassFish,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Sprng,Flask,…

使用流服务器m7s对接gb28181

优&#xff1a;sip品牌兼容性比较好&#xff0c;大华&#xff0c;海康都稳定可以&#xff0c;srs的5.0 sip品牌兼容性大华没反应&#xff0c;akstream-sip 大华也有问题&#xff0c;wvp也还可以 缺&#xff1a;目前最新的4.7.4版本&#xff0c;&#xff0c;sip协议用udp正常&a…

从零开始 Linux(一):基础介绍与常用指令总结

从零开始 Linux 01. 概念理解 1.1 什么是 Linux&#xff1f; Linux 是一个开源免费的 操作系统&#xff0c;具有很好的稳定性、安全性&#xff0c;且有很强的处理高并发的能力 Linux 的应用场景&#xff1a; 可以在 Linux 下开发项目&#xff0c;比如 JavaEE、大数据、Python…

Flink中StateBackend(工作状态)与Checkpoint(状态快照)的关系

State Backends 由 Flink 管理的 keyed state 是一种分片的键/值存储&#xff0c;每个 keyed state 的工作副本都保存在负责该键的 taskmanager 本地中。另外&#xff0c;Operator state 也保存在机器节点本地。Flink 定期获取所有状态的快照&#xff0c;并将这些快照复制到持…

Adobe Photoshop 2024 v25.4.0 - 专业的图片设计软件

Adobe Photoshop 2024 v25.4.0更新了&#xff0c;从照片编辑和合成到数字绘画、动画和图形设计&#xff0c;任何您能想象到的内容都能通过PS2024轻松实现。 利用人工智能技术进行快速编辑。学习新技能并与社区分享您的工作。借助我们的最新版本&#xff0c;做令人惊叹的事情从未…