数据结构之数组对栈的实现

news2024/12/1 0:30:16

目录

1.什么是栈

 2.栈的基本操作

3.栈的实现

1.结构体与函数接口

2.初始化栈

3.销毁栈

4.入栈

5.出栈

6.返回栈元素数量大小

7.判空

8.打印栈


1.什么是栈

栈是一种特殊的线性表,其中只允许固定的一端进行插入与删除,进行输出插入删除的那一端我们称为栈顶,与之相反的一端称为栈底。在栈中,元素遵循先进后出的原则即LIFO(last in first out)。

​栈因为是一种操作受到限制的线性表:栈的特点是先进后出,类似于堆盘子,先放到地上的盘子最后被取走。栈的操作有两种:入栈和出栈。入栈就是把元素放到栈顶,出栈就是把栈顶元素取出来。​我们也可以想象成弹夹,先装的子弹最后射出,后装的先射出。

 2.栈的基本操作

对于栈,我们对他的操作只有入栈与出栈,就栈里的元素,增加与删除,需要注意的是因为规定的特殊结构

压栈,也称入栈,进栈,(增加元素)

 

出栈(删除元素)

 因为这种特殊的结构,我们会发现在操作时栈底的元素永远也不可能在他的前一个出栈,无论何时出栈还是入栈。

 

3.栈的实现

栈的实现也是多种多样:

1.数组实现:数组实现优点较为明显,我们可以下标访问每个栈中的元素,且结构简单,空间利用率高,唯一的缺点是当容量不足时我们需要扩容。

2.单链表实现:单链表也可以实现栈这种结构,但需要注意我们在出栈与入栈的时候,是需要知道为节点的前一个元素,而单链表是无法直接访问的,需要遍历时间复杂度为O(n),于是我们在实现时,是利用头节点作为栈顶的,入栈即就是头插的方式可以实现栈的结构,对于入栈与出栈时间复杂度为O(1),不过单链表在访问栈中的元素时时间复杂度还是O(n).

3.双链表实现:最不建议的一种实现方式,因为对于双链表不仅增加了节点里的指针,结构更复杂,空间利用也不高,且也就是双链表的头插方式实现的,相对于前两种实现,没这个必要。

所以今天我们就用优点较为明显的数组来实现栈,我们也会发现栈的实现其实是非常简单的。

1.结构体与函数接口

我们在定义栈的结构体时,发现还是跟顺序表的定义一样,不过表示实际元素大小我们这里用top表示,即我们称为栈顶也是大小,同时给出总容量。

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>
#define DATAtype int 
typedef struct Stack
{
	DATAtype* a;//实现栈的数组
	int top;//记录栈顶
	int capacity;//总空间
	
}ST;

void Stackinit(ST**p);//初始化栈
void Stackdetroy(ST** p);//销毁栈
void Stackpush(ST** p, DATAtype x);//入栈
void Stackpop(ST** p);//出栈
int Stacksize(ST** p);//栈大小的返回
bool Stackempety(ST** p);//栈判空

2.初始化栈

我们这里初始化栈有 5个元素的大小空间,需要注意的是top的定义,因为在每次入栈之后top++,在进行打印时我们需要给它在减1,实现坐标的对应。top是当前元素的后一个元素的位置坐标,我们将这里定义为负1,打印时刚好打印a[0]元素,在进行迭代。

void Stackinit(ST* p)
{
	(p)->a = (DATAtype*)malloc(sizeof(DATAtype) * 5);
	(p)->capacity = 5;
	(p)->top = -1;//记录栈中数组位置

}

3.销毁栈

直接判空后free,在置为空。实现简单,不做赘述

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

4.入栈

入栈首先要对容量判断。因此这里还需要实现容量判断并扩容的操作,这里我直接定义一个函数。

入站的具体操作很简单,赋值并加加。

判断容量:

void chckcapacity(ST* p)
{
	//若容量不够,则扩容
	if ((p)->top == (p)->capacity)
	{
		DATAtype*tmp= (DATAtype*)realloc((p)->a,sizeof(DATAtype) * (p)->capacity * 2);
		if (tmp == NULL)
		{
			printf("realloc fail");
			return;
		}
		(p)->a = tmp;
		(p)->capacity = (p)->capacity * 2;

		printf("容量不够,已自动扩容,当前容量:%d\n", (p)->capacity);
	}
}

入栈:

void Stackpush(ST* p, DATAtype x)
{
	//检查容量
	chckcapacity(p);
	(p)->a[(p)->top] = x;
	(p)->top++;
}

5.出栈

操作也是简单,只要让数组访问不到即可,直接减减。

//出栈
void Stackpop(ST*p)
{
	(p)->top--;
	assert((p)->top);
	assert(p);
	//检查是否过量出栈
}

6.返回栈元素数量大小

很简单,返回top即可

//返回大小
int Stacksize(ST* p)
{
	assert(p);
	return (p)->top;
}

7.判空

bool Stackempety(ST* p)
{
	assert(p);
	if ((p)->top == NULL)
	{
		return true;
	}
	else
	{
		return false;
	}
}

8.打印栈

这个操作在定义top时需要注意一下,top是指向当前栈顶的下面那一个元素,在迭代打印时,注意访问是否越界的问题。

oid stackprintf(ST* p)
{
	assert(p);
	while ((p)->top>=0)
	{
		printf("%d->", (p)->a[(p)->top-1]);
		(p)->top--;
	}
}

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

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

相关文章

振幅调制器【Multisim】【高频电子线路】

目录 一、实验目的与要求 二、实验仪器 三、实验内容与测试结果 1、观测集电极调幅器输出信号波形&#xff0c;测量调幅度 2、观察集电极调幅器输出信号频谱&#xff08;Fourier analysis&#xff09; 3、改变V1幅度为0.8Vpk&#xff0c;观测输出波形&#xff0c;说明原…

MySQL函数详细

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️树高千尺&#xff0c;落叶归根人生不易&…

设计模式之【享元模式】,共享单车火起来并不是没有原因的

文章目录 一、什么是享元模式1、享元模式的角色2、享元模式应用场景3、享元模式的内部状态和外部状态4、享元模式的优缺点5、享元模式跟单例的区别6、享元模式跟缓存的区别7、享元模式注意事项及细节 二、实例1、享元模式一般写法2、俄罗斯方块案例3、购票业务案例4、数据库连接…

win2012/win2016/win2019 IIS部署SSL证书访问https(支持多站点)

请根据操作系统、站点部署数量选择以下相应参考文档&#xff0c;文档仅供参考。 A、windows2008iis7环境SSL部署https单/多站点 B、linux系统SSL部署https单/多站点 C、windows2003系统SSL单站点部署https 部署https(ssl)后设置301跳转将http跳转到https 亚数机房香港IP部…

(2022 EMNLP)(SEMGraph)将情感知识和眼动结合到一个图架构中

论文题目&#xff08;Title&#xff09;&#xff1a;SEMGraph: Incorporating Sentiment Knowledge and Eye Movement into Graph Model for Sentiment Analysis 研究问题&#xff08;Question&#xff09;&#xff1a;基于眼动的情感分析&#xff0c;旨在绘制基于眼动的情感关…

【Java多线程编程】解决线程的不安全问题之synchronized关键字

前言&#xff1a; 当我们进行多线程编程时候&#xff0c;多个线程抢占系统资源就会造成程序运行后达不到想要的需求。我们可以通过 synchronized 关键字对某个代码块或操作进行加锁。这样就能达到多个线程安全的执行&#xff0c;因此我把如何使用 synchronized 进行加锁的操作…

PVE安装高大全固件

PVE安装高大全的时候&#xff0c;把IMG挂在光驱上&#xff0c;发现无法运行。 后来明白了&#xff0c;openwrt的镜像直接就是个系统磁盘镜像&#xff0c; 没有引导启动项和安装程序&#xff0c;度娘和CSDN后才知道。 ———— 创建个虚拟机&#xff0c;按照引导创建虚拟机即…

女网红靠GPT-4交1000+男友,聊天按分钟收费,一周收入50万

来源 | 量子位 作者 | 鱼羊 注意看&#xff0c;这个女人叫卡琳&#xff0c;靠着GPT-4&#xff0c;她现在同时谈着1000男朋友。 对&#xff0c;我知道事情听上去有些离谱。就连GPT-4自己&#xff0c;都直呼“我一个AI都觉得非常不常见”。 但是先别急&#xff0c;因为更让人挠头…

一个用于Allen脑图谱基因数据的工具箱|abagen详细使用教程-获取基于脑区的基因表达矩阵(脑区*gene)

艾伦人类脑图谱&#xff08;Allen Human Brain Atlas&#xff09; 艾伦人类脑图谱是一个由艾伦脑科学研究所(Allen Institute for Brain Science)开发的在线基因表达图谱数据库&#xff0c;旨在提供人类大脑各个区域的细胞类型和基因表达信息。这个数据库包含了人类全基因组微…

工业识别与定位系统源码解决方案

工厂人员定位系统源码&#xff0c;工业领域定位系统源码 近年来人员定位系统在工业领域的发展势头迅猛&#xff0c;工业识别与定位成为促进制造业数字化的关键技术。通过实时定位可以判断所有的人、物、车的位置。实时定位系统要适用于复杂工业环境&#xff0c;单一技术是很难…

tinyWebServer 学习笔记——二、HTTP 连接处理

文章目录 一、基础知识1. epoll2. 再谈 I/O 复用3. 触发模式和 EPOLLONESHOT4. HTTP 报文5. HTTP 状态码6. 有限状态机7. 主从状态机8. HTTP_CODE9. HTTP 处理流程 二、代码解析1. HTTP 类2. 读取客户数据2. epoll 事件相关3. 接收 HTTP 请求4. HTTP 报文解析5. HTTP 请求响应 …

OpenText 数据迁移解决方案的工作原理及其优势

OpenText Migrate 让迁移变得简单 选择正确的迁移技术您所需要了解的事情 无痛迁移 当谈到停机的常见原因时&#xff0c;灾难往往会得到最多的关注。 但灾难只是导致停机的一小部分原因。 计划的停机时间造成了资源的真正消耗&#xff0c;许多纯粹为灾难恢复应运而生的工具和…

【Simulink】 0基础入门教程 P2 常用模块的使用介绍

目录 常用模块介绍 (1) relational operator&#xff0c;用于数值的大小比较 (2) compare to constant&#xff0c;用于和数值做大小比较 (3)logical operator&#xff0c;用于逻辑运算 与运算 或运算 非运算 (4) switch&#xff0c;类似于C语言中的if 语句&#xff0c…

stm32 MCU液晶TM1622 HT1622驱动调试

本文使用的例程软件工程代码如下 (1条消息) stm32MCU液晶TM1622HT1622驱动调试&#xff0c;源代码&#xff0c;实际项目使用资源-CSDN文库 HT1622/HT1622G/TM1622是一款常用的LCD驱动芯片 TM1622/HT1622厂家不一样&#xff0c;但是芯片功能基本上一直&#xff0c;硬件上基本…

『C++』C++的类型转换

「前言」文章是关于C特殊类型转换 「归属专栏」C嘎嘎 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 有些事不是看到了希望才去坚持&#xff0c; 而是因为坚持才会看到希望。 ——《十宗罪》 目录 一、C语言中的类型转换 二、为什么C需…

tinyWebServer 学习笔记——三、定时器处理非活跃链接

文章目录 一、基础知识1. 概念2. API3. 信号处理机制 二、代码解析1. 信号处理函数2. 信号通知逻辑3. 定时器4. 定时器容器5. 定时任务处理函数6. 使用定时器 参考文献 一、基础知识 1. 概念 非活跃&#xff1a;指客户端与服务器建立连接后&#xff0c;长时间不交换数据&…

第二章 数据的表示和运算

1.进位计数制 其他进制转十进制 二进制<——> 八进制&#xff0c;十六进制 (注意&#xff1a;小数部分也是从右往左算十进制——>任意进制&#xff08;整数部分&#xff09; 十进制——>任意进制&#xff08;小数部分&#xff09; 十进制转二进制&#xff08;拼凑…

【gitee流水线实现自动化部署】

首先进入自己的gitee仓库 创建流水线 配置基本信息 名称标识 事件监听 -----触发条件 主要是任务排编内 vue前端则选择node构建 这些就是字面意思 若无特殊需求 按照默认的即可 构建完之后添加新任务 主机部署 选择部署 主机部署 添加主机组 新建主机组 自主导入 之后配…

配置Git

1.安装Git git官网 2.配置Git 在点击桌面上的Git Bash快捷图标中输入&#xff1a; 配置用户名&#xff1a; git config --global user.name "username" //&#xff08; "username"是自己的账户名&#xff0c;&#xff09; 配置邮箱&#xff1a; git…

Mac终端主题配置

如果你不想安装item2这类第三方终端&#xff0c;可以试试我下面的步骤&#xff0c;先上效果图&#xff0c;如果感觉还符合你的胃口&#xff0c;可以继续读下去啦!!! 1.下载item2的主题安装包 https://github.com/mbadolato/iTerm2-Color-Schemes 2.解压缩&#xff0c;打开…