【数据结构】栈及其实现

目录

1.栈的概念及结构

2.栈的实现

2.1栈结构定义

2.2初始化及销毁

2.3插入数据

2.4删除数据

2.5访问栈顶数据

2.6判断是否为空栈

2.7计算栈的大小

3.8访问栈中所有数据


1.栈的概念及结构

栈:栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除操作

进行数据插入和删除操作的一端称为栈顶,另一端称为栈底

栈中的数据元素遵守后进先出LIFO(Last  In First Out)的原则

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

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

如下图为一个栈的结构:

上图中入栈顺序为:123456789

出栈顺序为:987654321

区分数据结构中的栈和内存中的栈:

内存区域划分:堆区,栈区,静态区,常量区......

一般操作系统中的栈指的是内存中的栈,数据结构中的栈是可以插入删除数据的栈

2.栈的实现

栈的实现一般可以使用数组或者链表实现,使用数组在尾插数据时的代价比较小,所以一般使用数组实现栈

2.1栈结构定义

栈结构的定义分为静态开辟和动态开辟两种

静态开辟时栈的空间大小是固定的,所以一般情况我们使用动态开辟

动态开辟的栈结构包括三个成员变量:数组指针,可以访问栈顶的top,栈的当前容量

📖Note:

我们创建的栈结构是数组形式的,所以可以通过下标访问,top即为时刻指向栈顶的下标

top也可以看作为栈中实际元素的个数

typedef int  STDataType;
//静态开辟
#define N 100
struct Stack
{STDataType a[N];int top;
};//动态内存开辟
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;

2.2初始化及销毁

初始化时对三个成员变量都要进行初始化

数组指针初始化为NULL

top = 0,同时指向栈底和栈顶,top可以看作为栈中实际元素的个数栈顶是动态变化的,每次插入数据或删除数据栈顶都会发生变化,而栈底是相对固定不变的

初始化时栈的容量为0,需要使用栈时再动态开辟空间

销毁时同样对三个结构成员分别置空或置0

//初始化
void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = ps->capacity = 0;
}
//销毁
void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}

2.3插入数据

插入数据首先要扩容,第一次插入我们开辟4个空间(根据需求),其他情况扩容为原来的二倍

📖Note:

以下代码中realloc的第二个参数应该是newcapacity * sizeof(STDataType)而不newcapacity

使用realloc函数扩容,第二个参数的单位是字节,是我们开辟空间的总字节数

扩容失败直接退出函数即可

扩容成功才可以插入数据

数组形式的栈中数据访问通过下标访问,栈结构的特殊性使其只能在栈顶进行数据的插入和删除,而top正是时刻指向栈顶的下标,所以使数据的插入和删除更加方便

//插入数据
void StackPush(ST* ps, STDataType x)
{assert(ps);//扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : (ps->capacity) * 2;STDataType* tmp = realloc(ps->a, newcapacity * sizeof(STDataType));//扩容失败if (tmp == NULL){perror("realloc fail");exit(-1);}//扩容成功ps->a = tmp;ps->capacity = newcapacity;}//插入数据ps->a[ps->top] = x;ps->top++;
}

下图是将12345一次压栈后栈中的结构 

2.4删除数据

数据的删除就更加方便,只要栈非空,指向栈顶的top直接向栈底方向移动一块空间即可

//删除数据
void StackPop(ST* ps)
{assert(ps);//栈不为空才能删除assert(!StackEmpty(ps));--ps->top;
}

2.5访问栈顶数据

访问栈顶数据的前提也是栈非空

注意数组的下标与元素的对应关系,数组的下标从0开时,所以第n个元素对应下标n-1

//访问栈顶数据
STDataType StackTop(ST* ps)
{assert(ps);//栈不为空才能访问assert(!StackEmpty(ps));return ps->a[ps->top - 1];
}

2.6判断是否为空栈

当栈中实际元素的个数为0时,栈即为空栈

//判断是否为空栈
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

2.7计算栈的大小

栈的大小即为栈中实际元素的个数,所以返回ps->top即可

//计算栈的大小
int StackSize(ST* ps) 
{assert(ps);return ps->top;
}

3.8访问栈中所有数据

栈中数据的访问只能从栈顶,当栈非空时,每次访问栈顶元素即可,访问栈顶的下一个元素需要栈顶元素先出栈,直至栈为空停止访问

//访问栈中数据
void StackPopAll(ST* ps)
{while (!StackEmpty(ps)){printf("%d ", StackTop(ps));StackPop(ps);}printf("\n");
}

 

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

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

相关文章

Oracle 开发篇+Java通过共享模式访问Oracle数据库

标签:共享服务器进程、shared server process释义:shared server process是Oracle的一种数据库连接技术,类似的还有专用模式和DRCP ★ 数据库配置 alter system set shared_server_sessions1 scopespfile; alter system set max_shared_serv…

FPGA优质开源项目 - UDP RGMII千兆以太网

本文介绍一个FPGA开源项目:UDP RGMII千兆以太网通信。该项目在我之前的工作中主要是用于FPGA和电脑端之间进行图像数据传输。本文简要介绍一下该项目的千兆以太网通信方案、以太网IP核的使用以及Vivado工程源代码结构。 Vivado 的 Tri Mode Ethernet MAC IP核需要付…

谈谈Spring与字节码生成技术

Java程序员几乎都了解Spring。 它的IoC(依赖反转)和AOP(面向切面编程)功能非常强大、易用。而它背后的字节码生成技术(在运行时,根据需要修改和生成Java字节码的技术)就是一项重要的支撑技术。 …

协程(一)单机--》并发--》协程

目录 一 协程的概述1.1 并行与并发1.2 线程1.3 新的思路1.4 Goroutine 二 第一个入门程序 一 协程的概述 我查看了网上的一些协程的资料,发现每个人对协程的概念都不一样,但是我认可的一种说法是:协程就是一种轻量级的线程框架(K…

uniapp软键盘谈起遮住输入框和头部被顶起的问题解决

推荐: pages.json中配置如下可解决头部被顶起和表单被遮住的问题。 { "path": "pages/debug/protocol/tagWord", "style": { "app-plus": { "soft…

基于Containerd容器引擎和kubeadm工具部署K8sv1.26.3

kubernetes master节点及node节点各核心组件的功能概述 master节点主要组件概述 master节点主要是k8s的控制节点,在master节点上主要有三个组件必不可少,apiserver、scheduler和controllermanager;etcd是集群的数据库,是非常核心的…

关于Postman如何配置随请求携带token

文章目录 一些吐槽实际应用 一些吐槽 首先吐槽一下 postman官网的文档说明,真是乱七八糟,一点都不清晰,能不能好好写用户手册啊(比如把用户都当作初始小白) 然后吐槽一下网上铺天盖地让我写js脚本应用全局access toke…

Oracle 知识篇+会话级全局临时表在不同连接模式中的表现

标签:会话级临时表、全局临时表、幻读释义:Oracle 全局临时表又叫GTT ★ 结论 ✔ 专用服务器模式:不同应用会话只能访问自己的数据 ✔ 共享服务器模式:不同应用会话只能访问自己的数据 ✔ 数据库驻留连接池模式:不同应…

kafka是有序的吗?如何保证有序?

首先,Kafka无法保证消息的全局有序性,这是因为Kafka的设计中允许多个生产者并行地向同一个主题写入消息。而且,一个主题可能会被划分为多个分区,每个分区都可以在独立的生产者和消费者之间进行并行处理。因此,生产者将…

js玩儿爬虫

前言 提到爬虫可能大多都会想到python,其实爬虫的实现并不限制任何语言。 下面我们就使用js来实现,后端为express,前端为vue3。 实现功能 话不多说,先看结果: 这是项目链接:https://gitee.com/xi1213/w…

为什么说要拥抱内容生成器ChatGPT,以学生为例说明

精灵从瓶子里出来了。 潘多拉的魔盒已经被打开。 纸已经包不住火了。 无论你喜欢用什么比喻来说明那些不可逆转的事情,现在都可以就把它们用到人工智能的出现。使用ChatGPT等AI工具生成的内容就在那里,而且不仅不会消失,还会越来越个性化&…

【80天学习完《深入理解计算机系统》】第三天 2.3 整数运算【正负溢出】【运算的溢出】【类型转换的二进制扩展】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)   文章字体风格: 红色文字表示&#…