数据结构之栈的实现

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:  Solitary-walk

      ⸝⋆   ━━━┓
     - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━  ➴ ⷯ

本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。

👑💎💎👑💎💎👑 
💎💎💎自💎💎💎
💎💎💎信💎💎💎
👑💎💎 💎💎👑    希望在看完我的此篇博客后可以对你有帮助哟

👑👑💎💎💎👑👑   此外,希望各位大佬们在看完后,可以互赞互关一下,看到必回
👑👑👑💎👑👑👑   

 今日本up主将为大家share 一下如何实现栈的基本操作

一·栈的初始化


二·栈的销毁


三·进栈


四·判断栈空


五·取栈顶元素


六·出栈


 这里姑且就以顺序栈为例

1.栈的特征就是先进后出

2.栈的构成:数据域,栈顶指针,栈的空间容量

3.注意栈顶指针只是用来指示位置的,并非真正的指针

1.初始化

因为我们采用的是顺序栈,所以这里就涉及到是用动态还是静态的数组

暂时选择动态的数组

初始状态栈空间容量是0

有个问题大家思考一下初始态我的top是为0还是为-1???,以及对应状态下所表示的逻辑意义

 

 其实对top 的初始值并没有强制性的规定只要是明白自己所写的top 的逻辑意义即可

这里就暂时以top = 0,来测试,一定要明白这一点,否则在自己进行敲代码的时候就会晕

 top = 0,表示当前top位置的下一个位置即为栈顶元素 的位置

 

void STInit(ST* pst)//栈的初始化
{assert(pst);//判断所传的结构体的指针是否为空pst->a = NULL;pst->capacity = pst->top = 0;// 注意这里top = 0,表示当前top位置的下一个位置即为栈顶元素 的位置//注意,以下所有接口函数都是基于top = 0 来执行的
}
2.销毁

 对于栈的销毁我们只需把数组所指向的 那一块空间进行free即可

free(pst->a);

void STDestroy(ST* pst)
{assert(pst);free(pst->a);//直接把这块空间free就行pst->a = NULL;
}
3进栈

草图如下:

1. 注意:因为top =  0,表示 当前top位置的下一个位置即为栈顶元素 的位置,此时元素的个数为0,如第一个图

在进栈的时候到底是先移top这个指针还是插入我的数据,注意此时top = 0哟

因为我是把数据放在top所对应的位置,所以就是先插入数据后移动top

若是先移动top指针后进行插入数据那所对应的topd 初始值就不是0了,而是我的top = -1

2.在插入数据的时候我们需要先判断是否为空

3.因为初始化之后我的数组空间为0,这里就需要进行开辟空间

 

  

void STPush(ST* pst,STDataType x)//进栈
{assert(pst);//先判断栈是否为空//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的int newcapacity ;if (pst->top == pst->capacity){newcapacity = pst->capacity == 0 ? 4 : 2 * (pst->capacity);//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的STDataType* tmp= (STDataType*)realloc(pst->a, newcapacity*sizeof(pst->capacity));//sizeof()求大小的时候是以字节为单位进行的if (tmp == NULL){perror("realloc faail\n");//为什么不用malloc return;}//来到这,扩容成功,对我的空间以及空间容量进行更新pst->a = tmp;pst->capacity = newcapacity;}//进栈操作pst->a[pst->top] = x;pst->top++;//永远指向栈顶元素下一个位置
}

 这里面有许多小点,稍不注意就会跳进坑,比如空间的开辟

还有就是栈容量初始是0,我们需要定义一个新的newcapacity来反映此时栈的容量,否则在后面空间开辟的时候就会有问题

大家可能就会写成下面的代码,这是错误滴

 

STDataType* tmp= (STDataType*)realloc(pst->a, capacity*sizeof(pst->capacity));//sizeof()求大小的时候是以字节为单位进行的

 

4.判空

 对于判空操作,我们这里只需看top == 0即可

 

bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;//没必要用if else,直接一步到位
}
5.出栈

出栈我们这里永远都是从栈顶的这个位置进行出栈,切忌,不要让我的top指针进行移动啊(也就是说,不要改变我top的值

重要的事情说三遍:永远都是从栈顶的这个位置进行出栈,永远都是从栈顶的这个位置进行出栈永远都是从栈顶的这个位置进行出栈

STDataType STTop(ST* pst)//取栈顶元素
{assert(pst);/*assert(STEmpty(pst));*/// 断言是否为空,这样写是错的assert(!STEmpty(pst));//正常逻辑,STEmpty(pst)应该是不为空,STEmpty(pst)这个函数返回0,!STEmpty(pst)取反操作就是1return  pst->a[pst->top-1];//因为top = 0,所以在用的时候先减1,指向当前栈顶元素//return  pst->a[pst->top--];注意这样写是错误的
}

 

return  pst->a[pst->top--];注意这样写是错误的

对于我们这些刚刚开始学习栈的小伙伴们来说,可能就会这样写,比如说,我就是之一

如果我们这里写成top--的话就会改变我们top  的值,也就是说top的位置就会变

对于我的top-1并不会改变我的top的一个值,即不会改变top的位置


Stack.c完整代码如下:

 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void STInit(ST* pst)//栈的初始化
{assert(pst);//判断所传的结构体的指针是否为空pst->a = NULL;pst->capacity = pst->top = 0;// 注意这里top = 0,表示当前top位置的下一个位置即为栈顶元素 的位置//注意,以下所有接口函数都是基于top = 0 来执行的
}
void STDestroy(ST* pst)
{assert(pst);free(pst->a);//直接把这块空间free就行pst->a = NULL;
}
void STPop(ST* pst)//出栈
{assert(pst);//assert(pst->top != 0);//为空就不能删除,也可以换种写法assert(!STEmpty(pst));//正常逻辑,STEmpty(pst)应该是不为空,STEmpty(pst)这个函数返回0,!STEmpty(pst)取反操作就是1//top 永远指向栈顶元素的下一个位置pst->top--;//直接top-- 就行,没有必要free}
void STPush(ST* pst,STDataType x)//进栈
{assert(pst);//先判断栈是否为空//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的int newcapacity ;if (pst->top == pst->capacity){newcapacity = pst->capacity == 0 ? 4 : 2 * (pst->capacity);//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的STDataType* tmp= (STDataType*)realloc(pst->a, newcapacity*sizeof(pst->capacity));//sizeof()求大小的时候是以字节为单位进行的if (tmp == NULL){perror("realloc faail\n");//为什么不用malloc return;}//来到这,扩容成功,对我的空间以及空间容量进行更新pst->a = tmp;pst->capacity = newcapacity;}//进栈操作pst->a[pst->top] = x;pst->top++;//永远指向栈顶元素下一个位置
}
bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;//没必要用if else,直接一步到位
}
STDataType STTop(ST* pst)//取栈顶元素
{assert(pst);/*assert(STEmpty(pst));*/// 断言是否为空,这样写是错的assert(!STEmpty(pst));//正常逻辑,STEmpty(pst)应该是不为空,STEmpty(pst)这个函数返回0,!STEmpty(pst)取反操作就是1return  pst->a[pst->top-1];//因为top = 0,所以在用的时候先减1,指向当前栈顶元素//return  pst->a[pst->top--];注意这样写是错误的
}

Stack.h完整代码如下:

#include<stdbool.h>
#include<assert.h>
//对顺序栈而言,有三部分,数据域,栈顶指针,栈的空间容量
typedef int STDataType;//类型重命名
typedef struct STStack
{STDataType* a;//数据域int top; // 栈顶指针int capacity;//栈的空间容量
}ST;void STInit(ST* pst);//栈的初始化
void STDestroy(ST* pst);//销毁
void STPush(ST* pst,STDataType x);//进栈
bool STEmpty(ST* pst);//判断栈是否为空
STDataType STTop(ST* pst);//取栈顶元素
void STPop(ST* pst);//出栈
//void STPrint(ST* pst);// 打印栈中元素,一般不这样写,不符合实际应用场景,都是一边访问一边打印,多用循环

ok以上就是我要 为大家share的一些基本操作,要是觉得还不错的话,烦劳各位大佬点个赞,互关一下呗,以便彼此留个联系方式,哈哈哈。

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

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

相关文章

J2EE项目部署与发布(Linux版本)->jdktomcat安装,MySQL安装,后端接口部署,linux单体项目前端部署

jdk&tomcat安装MySQL安装后端接口部署linux单体项目前端部署 1.jdk&tomcat安装 上传jdk、tomcat安装包 解压两个工具包 #解压tomcat tar -zxvf apache-tomcat-8.5.20.tar.gz #解压jdk tar -zxvf jdk-8u151-linux-x64.tar.gz 配置并且测试jdk安装 #配置环境变量 vim /e…

文件夹批量重命名:如何利用上级目录给多个文件夹进行高效重命名

在文件管理中&#xff0c;我们经常需要处理大量的文件和文件夹。其中&#xff0c;文件名过长或混乱的问题经常让我们感到困扰。这不仅影响了我们的工作效率&#xff0c;还可能导致一些错误。为了解决这个问题&#xff0c;我们可以用云炫文件管理器将“上级目录”批量重命名文件…

网络安全中的渗透测试主要有几个方面

渗透测试中主要有软件测试和渗透测试。 1、测试对象不同   软件测试&#xff1a;主要测试的是程序、数据、文档。 渗透测试&#xff1a;对象主要为网络设备、主机操作系统、数据库系统和应用系统。 2、测试内容不同   软件测试&#xff1a;主要工作内容是验证和确认&#x…

如何将word格式的文档转换成markdown格式的文档

如何将word格式的文档转换成markdown格式的文档 前言 A. 介绍Markdown和Word格式文档 什么是Markdown&#xff1f; Markdown是一种轻量级标记语言&#xff0c;旨在简化文本格式化和排版的过程。它以纯文本形式编写&#xff0c;通过使用简单的标记语法&#xff0c;使文档更具…

使用Objective-C和ASIHTTPRequest库进行Douban电影分析

概述 Douban是一个提供图书、音乐、电影等文化内容的社交网站&#xff0c;它的电影频道包含了大量的电影信息和用户评价。本文将介绍如何使用Objective-C语言和ASIHTTPRequest库进行Douban电影分析&#xff0c;包括如何获取电影数据、如何解析JSON格式的数据、如何使用代理IP技…

响应式设计疑难问题全解析!一篇读懂,立即上手

在我们当前的技术环境中&#xff0c;响应式设计已经成为前端开发的重要部分。其目标是让网站能够以最优的方式在任何设备上工作——不论是大屏电脑、笔记本、平板还是智能手机。这就要求网页能够自适应不同设备的屏幕大小。下面就让我们深入浅出地探讨响应式设计的精髓&#xf…

AI:50-基于深度学习的柑橘类水果分类

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…

Qt 使用QtXlsx操作Excel表

1.环境搭建 QtXlsx是一个用于读写Microsoft Excel文件&#xff08;.xlsx&#xff09;的Qt库。它提供了一组简单易用的API&#xff0c;可以方便地处理电子表格数据。 Github下载&#xff1a;GitHub - dbzhang800/QtXlsxWriter: .xlsx file reader and writer for Qt5 官方文档…

主机ping、ssh连接不通本地虚拟机

一、问题描述 在使用vscode remote ssh时&#xff0c;连接timeout&#xff0c;而且主机无论如何也ping不通虚拟机&#xff0c;但是虚拟机可以ping通主机。通过vagrant也可以连接虚拟机。 二、解决方案 试了网上包括设置remote ssh在内的许多方法都不行。重新查看主机和虚拟机…

15种稳定扩散模型的技术示例

推荐Stable Diffusion自动纹理工具&#xff1a; DreamTexture.js自动纹理化开发包 什么是稳定扩散模型&#xff1f; 潜在扩散模型 &#xff08;LDM&#xff09; 是一种图像生成技术&#xff0c;其工作原理是在潜在表示空间中迭代“去噪”数据&#xff0c;然后将表示解码为完整…

自己动手实现一个深度学习算法——二、神经网络的实现

文章目录 1. 神经网络概述1&#xff09;表示2&#xff09;激活函数3&#xff09;sigmoid函数4&#xff09;阶跃函数的实现5&#xff09;sigmoid函数的实现6)sigmoid函数和阶跃函数的比较7&#xff09;非线性函数8&#xff09;ReLU函数 2.三层神经网络的实现1&#xff09;结构2&…

设置防火墙

1.RHEL7中的防火墙类型 防火墙只能同时使用一张,firewall底层调用的还是lptables的服务: firewalld:默认 &#xff0c;基于不同的区域做规则 iptables: RHEL6使用&#xff0c;基于链表 Ip6tables Ebtables 2.防火墙的配置方式 查看防火墙状态: rootlinuxidc -]#systemct…

建议没用过这个的社区人都来试试!

不是吧&#xff0c;还有社区工作者不知道这个好东西嘛&#xff1f; 就是这个——写作火火&#xff0c;是写报告、方案一把好手啊 直接输入想写的内容&#xff0c;几秒钟报名啊方案啊就来了&#xff0c;不满意可以重新写&#xff0c;直到你满意为止&#xff0c;真的很方便。 …

[一] C++入门

摘要&#xff1a;OOP(面向对象)&#xff0c;namespace&#xff0c;cout and cin&#xff0c;缺省参数&#xff0c;函数重载&#xff0c;引用&#xff0c;内联函数&#xff0c;auto&#xff0c;范围 for&#xff0c;nullptr 20世纪80年代&#xff0c;计算机界提出了OOP(object o…

Hadoop RPC简介

数新网络-让每个人享受数据的价值https://www.datacyber.com/ 前 言 RPC&#xff08;Remote Procedure Call&#xff09;远程过程调用协议&#xff0c;一种通过网络从远程计算机上请求服务&#xff0c;而不需要了解底层网络技术的协议。RPC它假定某些协议的存在&#xff0c;例…

【计算机网络】计算机网络中的基本概念

文章目录 局域网LAN基于网线直连基于集线器组建基于交换机组建基于交换机和路由器组建 广域网WANIP地址端口号协议为什么要有协议知名协议的默认端口 五元组协议分层TCP/IP五层模型封装和分用 网络互连就是将多台计算机连接在一起&#xff0c;完成数据共享。数据共享本质是网络…

查询平均提速 700%,奇安信基于 Apache Doris 升级日志安全分析系统

本文导读&#xff1a; 数智时代的到来使网络安全成为了不可忽视的重要领域。奇安信作为一家领先的网络安全解决方案领军者&#xff0c;致力于为企业提供先进全面的网络安全保护&#xff0c;其日志分析系统在网络安全中发挥着关键作用&#xff0c;通过对运行日志数据的深入分析…

正则表达式续篇

位置锚定&#xff1a; ^:行首锚定&#xff0c;表示以什么为开头 例如&#xff1a; $:行尾锚定&#xff0c;表示以什么为结尾 例如&#xff1a; ^&#xff1a;匹配的是空行 例如&#xff1a; ^root$&#xff1a;匹配整行&#xff0c;而且整行只能有这一个字符串 实验&#x…

软考之软件工程基础理论知识

软件工程基础 软件开发方法 结构化方法 将整个系统的开发过程分为若干阶段&#xff0c;然后依次进行&#xff0c;前一阶段是后一阶段的工作依据按顺序完成。应用最广泛。特点是注重开发过程的整体性和全局性。缺点是开发周期长文档设计说明繁琐&#xff0c;工作效率低开发前要…