一篇文章带你实现栈的接口

news2025/2/8 2:50:49

一,什么是栈

栈(Stacks)是限定在一端插入和删除的线性表。允许插入和删除的一端称为栈顶(Top),另一端称为栈底(Bottom)。栈中的数据元素遵守后进先出(Last In First Out)的原则。因此,栈又称为后进先出(先进后出)线性表。

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

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

如图所示:

 二,栈的实现

栈的实现一般有两种存储方法,顺序栈(数组)和链栈(链表)。

这里我们采用顺序栈。

 

2.1,栈的结构

这里采用支持动态增长的栈,用a来指向空间中对应数组的地址。用top来表示栈顶,用capcity表示容量,到后面容量不够扩容用。

typedef int SDataType;
typedef struct Stack
{
	SDataType* a;//数组存储数据
	int top;//栈顶
	int capcity;//容量
}ST;

2.2,栈的接口

void STInit(ST* p);//栈的初始化
void STPush(ST* p, SDataType x);//压栈
bool STEmpty(ST* p);//判断数据是否为空
void STPop(ST* p);//出栈
SDataType STTop(ST* p); //取栈顶数据
void STDestroy(ST* p);//栈的销毁
int STSize(ST* p);//栈的大小

三,接口的实现。

3.1,栈的初始化

这里先申请一个4个字节的空间。容量为4。top可以是0,也可以是1。

void STInit(ST* p)//栈的初始化
{
	assert(p);
	p->a = (SDataType*)malloc(sizeof(SDataType)*4);
	p->top = -1;//top = 0 时是栈顶的下一个位置。top =-1 是栈顶的位置。
	p->capcity = 4;
}

3.2,栈的插入(压栈)

这里插入数据前判断一下容量是否充足,如果不足,就用realloc扩容成原来容量的2倍。最后将x插入到栈顶中。注意:p->top++;//这里加加后,访问栈顶的元素直接可以用a[p->top]

void STPush(ST* p, SDataType x)//压栈
{
	assert(p);
	if (p->capcity == p->top + 1)
	{
		SDataType* tmp = (SDataType*)realloc(p->a, sizeof(SDataType) * p->capcity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
		}
		p->a = tmp;
		p->capcity *= 2;

	}
	p->a[p->top + 1] = x;
	p->top++;//这里加加后,访问栈顶的元素直接可以用a[p->top]

}

3.3,出栈

这里在top减一之前需要判断一下栈是否为空的情况。

void STPop(ST* p)//出栈
{
	assert(p);
	assert(!STEmpty(p));//判断是否为空
	p->top--;
}

栈为空的实现

这里bool(布尔值)的头文件为:stdbool.h,如果为空返回1,不为空等号不成立,返回0;

bool STEmpty(ST* p)
{
	assert(p);
	return p->top + 1 == 0;
}

3.4,获取栈顶元素

这里还是判断一下是否为空,然后返回栈顶元素。

SDataType STTop(ST* p) //取栈顶数据
{
	assert(p);
	assert(!STEmpty(p));
	return p->a[p->top];
}

3.5,栈的大小

这里判断完非空后,直接返回top+1(看完上面的压栈程序中,这里可以把top理解成数组下标,加一是总大小)。

int STSize(ST* p)//栈的大小
{
	assert(p);
	assert(!STEmpty(p));
	return p->top + 1;
}

3.6,栈的销毁

把申请的空间释放,再置为空。其余赋值为0;

void STDestroy(ST* p)//栈的销毁
{
	assert(p);
	free(p->a);
	p->a = NULL;
	p->capcity = 0;
	p->top = 0;
}

四,总代码

//test.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int SDataType;
typedef struct Stack
{
	SDataType* a;//数组存储数据
	int top;//栈顶
	int capcity;//容量
}ST;
void STInit(ST* p);//栈的初始化
void STPush(ST* p, SDataType x);//压栈
bool STEmpty(ST* p);//判断数据是否为空
void STPop(ST* p);//出栈
SDataType STTop(ST* p); //取栈顶数据
void STDestroy(ST* p);//栈的销毁
int STSize(ST* p);//栈的大小

//stack.c接口的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include"test.h"
void STInit(ST* p)//栈的初始化
{
	assert(p);
	p->a = (SDataType*)malloc(sizeof(SDataType)*4);
	p->top = -1;//top = 0 时是栈顶的下一个位置。top =-1 是栈顶的位置。
	p->capcity = 4;
}
void STPush(ST* p, SDataType x)//压栈
{
	assert(p);
	if (p->capcity == p->top + 1)
	{
		SDataType* tmp = (SDataType*)realloc(p->a, sizeof(SDataType) * p->capcity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
		}
		p->a = tmp;
		p->capcity *= 2;

	}
	p->a[p->top + 1] = x;
	p->top++;

}
void STPop(ST* p)//出栈
{
	assert(p);
	assert(!STEmpty(p));
	p->top--;
}
SDataType STTop(ST* p) //取栈顶数据
{
	assert(p);
	assert(!STEmpty(p));
	return p->a[p->top];
}
void STDestroy(ST* p)//栈的销毁
{
	assert(p);
	free(p->a);
	p->a = NULL;
	p->capcity = 0;
	p->top = 0;
}
int STSize(ST* p)//栈的大小
{
	assert(p);
	assert(!STEmpty(p));
	return p->top + 1;
}
bool STEmpty(ST* p)
{
	assert(p);
	return p->top + 1 == 0;
}
//test.c接口的测试
#define _CRT_SECURE_NO_WARNINGS 1
#include"test.h"
int main()//测试
{
	ST s;
	STInit(&s);
	STPush(&s, 0);
	printf("%d\n", STTop(&s));
	STPush(&s, 1);
	printf("%d\n", STTop(&s));
	STPush(&s, 2);
	printf("%d\n", STTop(&s));
	STPush(&s, 3);
	printf("%d\n", STTop(&s));
	STPop(&s);
	STPop(&s);
	printf("%d\n", STTop(&s));

	printf("%d\n", STSize(&s));
	return 0;
}

好了,到这里就该结束了。希望对大家有所帮助!

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

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

相关文章

Mysql索引篇——Day01

Mysql索引篇——Day01 什么是索引&#xff1f;索引的分类按数据结构分按物理存储分按字段特性分类按字段个数分类 什么时候需要创建索引/不需要创建索引&#xff1f;优化索引的方法前缀索引优化覆盖索引优化主键索引最好是自增的索引最好设置为 NOT NULL防止索引失效 什么是索引…

Java基础入门篇——Java Number Math 类

当我们在Java中处理数字和执行数学计算时&#xff0c;可以使用Java的Number和Math类。这两个类提供了一系列方法和常量&#xff0c;用于处理和操作数字数据。 1、Number类&#xff1a; Number是一个抽象类&#xff0c;是Java中所有数字类的父类&#xff0c;包括Byte、Short…

设计模式(6)原型模式

一、介绍 Java中自带的原型模式是clone()方法。该方法是Object的方法&#xff0c;native类型。他的作用就是将对象的在内存的那一块内存数据一字不差地再复制一个。我们写简单类的时候只需要实现Cloneable接口&#xff0c;然后调用Object::clone方法就可实现克隆功能。这样实现…

1.物联网IWIP网络

一。以太网 1.nc模拟UDP &#xff08;1&#xff09;COMMBOX通信调试工具 &#xff08;2&#xff09; 控制台输入nc -u 127.0.0.1 8000,此时串口也可以获得数据 &#xff08;3&#xff09;串口调试程序发送字符串&#xff0c;电脑控制台也会展示同样字符串&#xff08;说明UDP…

java文件

一.File类 二.扫描指定目录&#xff0c;并找到名称中包含指定字符的所有普通文件&#xff08;不包含目录&#xff09;&#xff0c;并且后续询问用户是否要删除该文件 我的代码: import java.io.File; import java.io.IOException; import java.util.Scanner;public class Tes…

对于msvcr120.dll丢失的问题,分享几种解决方法

msvcr120.dll的作用是提供一系列的运行时函数和功能&#xff0c;以便应用程序能够正常运行。这些函数和功能包括内存管理、异常处理、输入输出操作、数学运算等。在没有这个库文件的情况下&#xff0c;应用程序可能无法正常启动或执行特定的功能&#xff0c;甚至会出现错误提示…

Spring MVC【一篇搞定】

Spring MVC 文章目录 Spring MVC一、什么是 Spring MVC二、介绍MVC2.1、Spring MVC 和 MVC 之间的关系 三、创建 Spring MVC四、掌握 Spring MVC 的核心 ☆☆☆☆4.1、Spring 热部署4.2、实现用户与程序的连接 ☆4.2.1、RequestMapping4.2.2、GetMapping/PostMapping 4.3、获取…

《Zookeeper》源码分析(七)之 NIOServerCnxn的工作原理

目录 NIOServerCnxnreadPayload()handleWrite(k)process() NIOServerCnxn 在上一节IOWorkRequest的doWork()方法中提到会将IO就绪的key通过handleIO()方法提交给NIOServerCnxn处理&#xff0c;一个NIOServerCnxn代表客户端与服务端的一个连接&#xff0c;它用于处理两者之间的…

JavaScript 中 let 和 var 的区别

首先&#xff0c;let 和 var 都是用于声明变量的关键字&#xff0c;在老版 JavaScript 中也许你会见到 var 方式来声明变量&#xff0c;而现如今几乎都是使用 let 进行声明&#xff0c;接下来看看这两个关键字之间的区别。 1、作用域 var var 声明的变量在函数内部有效&#x…

【什么是应变波齿轮又名谐波驱动?机器人应用的完美齿轮组!?】

什么是应变波齿轮又名谐波驱动&#xff1f;机器人应用的完美齿轮组&#xff01;&#xff1f; 1. 什么是应变波齿轮&#xff1f;2. 工作原理3. 应变波齿轮 – 谐波驱动 3D 模型4. 3D 打印应变波齿轮 – 谐波驱动5. 总结 在本教程中&#xff0c;我们将学习什么是应变波齿轮&#…

关于使用 heatmap.js创建热力图并应用在cesuim上的坐标定位问题

废话少说&#xff0c;heatmap.js的用法我不在赘述&#xff0c;此文主要解决其热力点坐标定位在cesuim上的问题。 热力图容器 我们知道&#xff0c;热力图需要用有一个容器节点来存放它生成的图片&#xff1a;<div class"div-heatMap"></div> 而其中容器…

【ElasticSearch入门】

目录 1.ElasticSearch的简介 2.用数据库实现搜素的功能 3.ES的核心概念 3.1 NRT(Near Realtime)近实时 3.2 cluster集群&#xff0c;ES是一个分布式的系统 3.3 Node节点&#xff0c;就是集群中的一台服务器 3.4 index 索引&#xff08;索引库&#xff09; 3.5 type类型 3.6 doc…

360安全卫士右下角广告弹窗太多怎么彻底关闭?

360安全卫士右下角广告弹窗太多怎么彻底关闭&#xff1f; 1、卸载360安全卫士&#xff0c;选择继续卸载&#xff0c;并点击下一步&#xff1b; 2、选择广告弹窗太多&#xff0c;并点击下一步&#xff1b; 3、然后被告知升级极速版永久去广告&#xff0c;可以点击一键去广告。 …

全网超全,接口自动化测试-动态数据生成/替换数据(实战应用)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口自动化过程中…

拂袖一挥,zipfile秒列zip包内容

使用wxpython列出文件夹中的zip文件及内容 最近在做一个文件管理的小工具,需要列出选择的文件夹下的所有zip压缩文件,并在点击某个zip文件时能够显示其中的内容。为此我使用了wxpython来实现这个功能。 1. 导入需要的模块 首先导入程序需要的模块: import wx import os imp…

【C++面向对象】--- 继承 的奥秘(上篇)

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

git强推覆盖其他项目分支

git强推分支&#xff0c;覆盖其他分支&#xff1b; 操作&#xff1a; 下载branch-1.3代码&#xff1b; $ git clone gitlabgitlab.zte.net:zte-dba-service/branch.git $ git remote add origin2 gitlabgitlab.zte.net:zte-service/branch.git $ git push origin2 master -f注…

UE 5 GAS 在项目中处理AttributeSet相关

这一篇文章是个人的实战经验记录&#xff0c;如果对基础性的内容不了解的&#xff0c;可以看我前面一篇文章对基础的概念以及内容的讲解。 设置AttributeSet 使用GAS之前&#xff0c;首先需要设置参数集AS&#xff0c;这个是用于同步的一些参数&#xff0c;至于如何设置GAS&a…

腾讯云Linux服务器创建、使用和配置的教程

腾讯云Linux服务器创建&#xff0c;先注册腾讯云账号&#xff0c;购买云服务器配置然后选择Linux镜像操作系统&#xff0c;包括云服务器地域、CVM实例、公网IP等配置&#xff0c;然后远程链接到腾讯云服务器快速配置使用教程&#xff1a; 目录 腾讯云Linux服务器创建 创建Li…

远程控制医疗行业应用解析:如何满足医院合规需求?

远程控制医疗行业应用解析&#xff1a;如何满足医院合规需求&#xff1f; 作为一个起源于IT行业的技术&#xff0c;以远程桌面为基础的远程控制技术目前在医疗领域也已经有了比较广阔的应用前景&#xff0c;尤其是在医疗数字化系统/设备的远程运维场景&#xff0c;已经有了一些…