简单数据结构——栈和队列1(栈超全)(初始化,销毁,出栈入栈销毁实现,例题运用)

知识特点

类似数据表链表,在逻辑上依次存储,但对比顺序表和链表有所限制,不能随便存储

一定要先掌握顺序表的实现,本人博客有顺序表专栏大家可以自行查看,看懂顺序表专栏之后再来了解栈的实现会更容易懂。

如果还没有掌握顺序表可以先收藏本篇文章再进行查看本篇内容。

1.栈

1.1栈的概念和结构

一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除的一端叫做栈顶,另一端叫做栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

删除数据:出栈

栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶:压栈

 类比:羽毛球桶和弹夹(后压进去的先出来)

 单链表/双链表都可以实现栈

2.栈的实现

2.1选择实现方式

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的 代价比较小

首先不选择双链表:对比单链表还有2倍指针,不宜维护,更加复杂化了

数组实现栈缺点:插入数据不够了需要扩容,自身有消耗,但是开辟空见释放空间调用速度很快,所以影响不大

数组实现栈优点:cpu高速缓存速率很快

数组和单链表相差不大,我们选择数组来实现

2.2栈的实现创建头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;//用size也可以,两者都行int capacity;
}ST;
//初始化和销毁
void STInit(ST* pst);
void STDestroy(ST* pst);//实现插入,不用分头插尾插,因为只能从栈顶插入
void STPush(ST*pst,STDataType x);
void STPop(ST* pst);//取栈顶数据//形参需要传过来指针,否则实现完初始化之后无法传回去
//这一部分在结构体里又讲(大家可以去看侧栏合集)
// //  获取栈顶数据
STDataType STTop(ST* pst);//提供两个接口
bool STEmpty(ST* pst);//判断栈是否为空//获取栈里面的数据个数
int STSize(ST* pst);

 vs中实现图:

2.3栈的实现创建源文件

2.3.1需要注意top(为什么pst->top=-1;)

1.top到底是只想哪里呢?(top指向栈顶数据,但是有两个方法表示)

指向栈顶还是指向栈顶的下一个元素呢?

其实是根据自己的定义来的

 法一:(top指向栈顶元素)
若想要top直接指向栈顶元素,那么初始化的时候top就不能为0

因为top如果为0就无法清楚此时到底是有元素还是没有元素(存在误导)。

所以top一开始初始化就应该指向-1,这样top指向0的时候就可以表示为指向了第一个元素,类似于数组,第一个元素下标为0,第二个元素下标为1;(top指向栈顶元素)

法二:(top指向栈顶下一个元素)

如果top指向了栈顶,直接指向0,那么说明第一个元素指向了1;

(类比size的用法就可)

注意:两种方式都可以,但是前后需要匹配

若pst->top=0;说明top指向栈顶数据的下一个位置。

若pst->top=-1;说明top指向栈顶数据。

一定要区分清楚!!!!!!(用数组设计栈的关键点)

不能误认为top初始化为0并且top还指向栈顶元素。

选择一个方式就行(我们选择初始化为0的方式,也就是说指向栈顶元素的下一个元素,而不是栈顶元素)

2.3.2为什么不能直接用结构体引用而是要用函数呢?

    是否可以用直接自行访问数据?
 

(建议还是要规范运用函数调用而不是自己调用,很容易出错)

2.3.3实现

#include"Stack.h"
void STInit(ST* pst)
{assert(pst);//首先需要断言传过来的不能是空指针//然后开始对方法中的每一个成员变量初始化pst->a = NULL;pst->top = 0;//(已经讲解)pst->capacity = 0;
}
//摧毁
void STDestroy(ST* pst)
{assert(pst);free(pst->a);//free掉之后记得要置为空pst->a = NULL;pst->top = pst->capacity = 0;
}//入栈出栈
void STPush(ST* pst, STDataType x)
{assert(pst);//实 现的第一步都是先进行断言//当top==capacity时说明容量已经满了,此时需要扩容if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));if (tmp == NULL)//如果没有开辟成功就直接报错{perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity; }pst->a[pst->top] = x;pst->top++;//存入数据之后top需要+1
}   
//出栈
void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--; 
}  
//取栈顶数据
STDataType STTop(ST* pst)
{assert(pst);assert(pst->top>0);return pst->a[pst->top - 1];//返回
}bool STEmpty(ST* pst)
{assert(pst);return pst->top==0;//因为top指向的是栈顶的后面一个元素,因此如果是返回0的话说明该栈为空,没有任何元素;
}//这里是判断真假int STSize(ST* pst)
{assert(pst);return pst->top;//我们是用法二来定义top的,所以top的使用与size类似,因此,数据个数可以直接返回top就可以计算出来
}

3.栈的例题(括号匹配)

题目:

 

解答:

//利用栈的思想来解题
//在c语言中首先要创建一个栈
#pragma once 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef char STDataType;//因为是字符

typedef struct Stack
{
    STDataType* a;
    int top;
    int capacity;
}ST;

// 初始化和销毁
void STInit(ST* pst);
void STDestroy(ST* pst);

// 入栈  出栈
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);

// 取栈顶数据
STDataType STTop(ST* pst);

// 判空
bool STEmpty(ST* pst);
// 获取数据个数
int STSize(ST* pst);


// 初始化和销毁
void STInit(ST* pst)
{
    assert(pst);

    pst->a = NULL;
    // top指向栈顶数据的下一个位置
    pst->top = 0;

    // top指向栈顶数据
    //pst->top = -1;

    pst->capacity = 0;
}

void STDestroy(ST* pst)
{
    assert(pst);

    free(pst->a);
    pst->a = NULL;
    pst->top = pst->capacity = 0;
}

// 入栈  出栈
void STPush(ST* pst, STDataType x)
{
    assert(pst);

    // 扩容
    if (pst->top == pst->capacity)
    {
        int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
        STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }

        pst->a = tmp;
        pst->capacity = newcapacity;
    }

    pst->a[pst->top] = x;
    pst->top++;
}

void STPop(ST* pst)
{
    assert(pst);
    assert(pst->top > 0);

    pst->top--;
}


// 取栈顶数据
STDataType STTop(ST* pst)
{
    assert(pst);
    assert(pst->top > 0);

    return pst->a[pst->top - 1];
}

// 判空
bool STEmpty(ST* pst)
{
    assert(pst);

    return pst->top == 0;
}

// 获取数据个数
int STSize(ST* pst)
{
    assert(pst);

    return pst->top;
}

bool  isValid(char* s)
{
    //新建一个成员变量st
    ST st;
    STInt(&st);
    while (*s)//如果是\0就直接结束了
    {
        //如果是左括号就入栈
        if (*s == '(' || *s == '[' || *s == '{')
        {
            STPush(&st, *s);//入栈
        }
        else//右括号取栈顶左括号尝试匹配
        {
            char top = STTop(&st);
            STPop(&st);//取出一个,删除一个方便取出
            //如果判断匹配,那如果匹配还要再进行下一个比对,因此可以直接判断不匹配的情况
            if ((top == '(' && *s != ')') || (top == '[' && *s != ']')
                || (top == '{' && *s != '}'))
            {
                STDestroy(&st);
                return false;
            }
        }
        ++s;
    }
    //不用栈记得销毁,避免内存泄漏

    //栈不为空,说明左括号比右括号多,数量不匹配
    bool ret = STEmpty(&st);
    STDestroy(&st);
    return ret;
}

完-

这一篇属于将前面几节内容串起来加上运用的知识,所以如果尽量先把前面内容搞懂。

看到这里不容易,这篇内容比较多写了2天,如果有帮助的话,希望得到您的点赞收藏哦。感谢认可,接下来会继续更新队列相关知识点

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

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

相关文章

使用DBeaver连接postgreSql提示缺少驱动

重新安装电脑之后用dbeaver链接数据库的时候&#xff0c;链接PG库一直提示缺少驱动&#xff0c;当选择下载驱动的时候又非常非常慢经常失败&#xff0c;尝试了一下更改源然后下载库驱动就非常快了&#xff0c;当然也包括dbeaver的自动更新。 方法&#xff1a;点击菜单栏【窗口…

闲来装个虚拟机Ubuntu24.04和硬盘分区及挂载

简述 最近ubuntu出新版本了&#xff0c;ubuntu24.04&#xff0c; 俗称高贵食蚁兽。5年前进行Android或者linux开发基本是在windows下的虚拟机中进行。目前&#xff0c;虽然物质基础提高了&#xff0c;功能有独立进行编译、代码管理的服务器了。可以通过ssh登录&#xff0c;但是…

Seata之AT 模式的使用

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Seata 是一款开源的…

ChIP-seq染色质图谱检测方法的局限性及改善方式

ChIP-seq是最广泛使用的染色质图谱检测方法&#xff0c;但有很大的局限性&#xff0c;具体表现为&#xff1a; 1.高细胞需求量&#xff1b; 2.低吞吐量&#xff1b; 3.技术困难&#xff1b; 4.高成本&#xff0c;深度测序&#xff1b; 5.数据质量差&#xff0c;变量大 CUT&…

使用CNN或resnet,分别在flower5,flower17,flower102数据集上实现花朵识别分类-附源码-免费

前言 使用cnn和resnet实现了对flower5&#xff0c;flower17&#xff0c;flower102数据集上实现花朵识别分类。也就是6份代码&#xff0c;全部在Gitee仓库里&#xff0c;记得点个start支持谢谢。 本文给出flower17在cnn网络实现&#xff0c;flower102在resnet网络实现的代码。…

docker私有仓库的registry

简介 Docker私有仓库的Registry是一个服务&#xff0c;主要用于存储、管理和分发Docker镜像。具体来说&#xff0c;Registry的功能包括&#xff1a; 存储镜像&#xff1a;Registry提供一个集中的地方来存储Docker镜像&#xff0c;包括镜像的层次结构和元数据。 版本控制&…

基于HSI模型的水下图像增强算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

【数据结构】-- 链表专题

链表的分类 前面我们实现了单链表&#xff0c;单链表只是链表的一种。可以根据以下几个标准来判断链表的类型&#xff1a; 1.单向或者双向 如图所示&#xff0c;单向链表中一个节点的指针域只储存了下一个节点的指针&#xff0c;能通过前一个节点访问后一个节点&#xff0c;无…

【4089】基于小程序实现的互动打卡系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

怎么写毕业论文的? 推荐4个AI工具

写作这件事一直让我们从小学时期就开始头痛&#xff0c;初高中时期800字的作文让我们焦头烂额&#xff0c;一篇作文里用尽了口水话&#xff0c;拼拼凑凑才勉强完成。 大学时期以为可以轻松顺利毕业&#xff0c;结果毕业前的最后一道坎拦住我们的是毕业论文&#xff0c;这玩意不…

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发 搭建短视频矩阵系统源码的交付步骤可以概括为以下几个关键环节&#xff1a; 1. **系统需求分析**&#xff1a;明确系统需要支持的功能&#xff0c;如短视频的上传、存储、播放、分享、评论、点赞等。 2. **技术选…

Python深度学习基于Tensorflow(5)机器学习基础

文章目录 监督学习线性回归逻辑回归决策树支持向量机朴素贝叶斯 集成学习BaggingBoosting 无监督学习主成分分析KMeans聚类 缺失值和分类数据处理处理缺失数据分类数据转化为OneHot编码 葡萄酒数据集示例 机器学习的流程如下所示&#xff1a; 具体又可以分为以下五个步骤&#…

Python开源工具库使用之运动姿势追踪库mediapipe

文章目录 前言一、姿势估计1.1 姿态关键点1.2 旧版 solution API1.3 新版 solution API1.4 俯卧撑计数 二、手部追踪2.1 手部姿态2.2 API 使用2.3 识别手势含义 参考 前言 Mediapipe 是谷歌出品的一种开源框架&#xff0c;旨在为开发者提供一种简单而强大的工具&#xff0c;用…

[C++核心编程-04]----C++类和对象之封装

目录 引言 正文 01-类和对象简介 02-封装简介 03-封装的意义 04-封装案例之设计学生类 05-封装的权限控制 06-struct和class的区别 07-成员属性设置为私有 08-封装案例1-设计立方体 09-封装案例2-判断点和圆的关系 总结 引言 在C中&#xff0c;…

Failed to build flash-attn:ERROR: Could not build wheels for flash-attn

安装 FlashAttention 的时候遇到报错&#xff1a; Failed to build flash-attn ERROR: Could not build wheels for flash-attn, which is required to install pyproject.toml-based projects可能是安装的版本与环境存在冲突吧&#xff0c;我的环境是&#xff1a; python 3.1…

堆的应用2——TOPK问题

TOPK问题 TOP-K问题&#xff1a;即求数据结合中前K个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大。 比如&#xff1a;专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。 情况1——数据量小 对于Top-K问题&#xff0c;能想到的最简单直接的方式就…

嵌入式C语言高级教程:实现基于STM32的自适应交通信号控制系统

自适应交通信号控制系统能够基于实时交通流数据调整信号灯的时长&#xff0c;提高路口的通行效率。本教程将指导您如何在STM32微控制器上实现一个基本的自适应交通信号控制系统。 一、开发环境准备 硬件要求 微控制器&#xff1a;STM32F103C8&#xff0c;具备足够的处理能力…

Eclipse下载安装教程(包含JDK安装)【保姆级教学】【2023.10月最新版】

目录 文章最后附下载链接 第一步&#xff1a;下载Eclipse&#xff0c;并安装 第二步&#xff1a;下载JDK&#xff0c;并安装 第三步&#xff1a;Java运行环境配置 安装Eclipse必须同时安装JDK &#xff01;&#xff01;&#xff01; 文章最后附下载链接 第一步&#xf…

[法规规划|数据概念]金融行业数据资产和安全管理系列文件解析(3)

“ 金融行业在自身数据治理和资产化建设方面一直走在前列。” 一直以来&#xff0c;金融行业由于其自身需要&#xff0c;都是国内开展信息化建设最早&#xff0c;信息化程度最高的行业。 在当今数据要素资产化的浪潮下&#xff0c;除了行业自身自身数据治理和资产化建设方面&am…

EditReady for Mac激活版:专业视频转码工具

对于视频专业人员来说&#xff0c;一款高效的视频转码工具是不可或缺的。EditReady for Mac正是这样一款强大的工具&#xff0c;它拥有简洁直观的操作界面和强大的功能&#xff0c;让您的视频处理工作事半功倍。 EditReady for Mac支持多种视频格式的转码&#xff0c;并且支持常…