栈和队列(C语言)

目录

数据结构之栈

定义

 实现方式

基本功能实现

1)定义,初始化栈

2)入栈

3)出栈

4)获得栈顶元素

5)获得栈中有效元素个数

6)检测栈是否为空

7)销毁栈

数据结构之队列 

定义

实现方式

基本功能实现

1)定义,初始化队列

2)入队

3)出队

4)获得队列头部元素

5)获得队尾元素

6)队列元素个数

7)队列是否为空

8)销毁队列

栈和队列练习

1.1 有效括号

用栈的先入后出性质


数据结构之栈

定义

栈:一种特殊的线性表,其特点是只允许在一端进行插入和删除的操作,这一端叫做栈顶,另一端叫做栈底;栈中的数据使用的时候必须遵行先入后出(先进入的后出来)的原则就好比一群人上电梯,最先进去的站在里面,最后出来,而最后上来的站在门口,最先出来。

压栈:向栈顶插入元素;

出栈:将栈顶元素删去;

原则:入栈和出栈的操作对象都是栈顶。

 实现方式

栈的实现方式有两种,可以用前面的顺序表也可以使用链表。

1)使用链表实现,要记录尾节点(避免遍历链表找尾)方便压栈;同时还要记录倒数第二个节点,方便出栈时,将尾节点释放。所以一共需要定义两个结构体:链表结构体,结构体(记录头节点,尾节点,倒数第二个节点);

2)使用顺序表实现,顺序表有栈内的总个数,可以直接找到尾,也可以直接出栈,相比于链表更简单。所以我们更推荐使用顺序表来实现栈。

顺序表(含通讯录)-CSDN博客文章浏览阅读743次,点赞16次,收藏11次。C语言实现顺序表及其基本功能的实现,包含通讯录项目。https://blog.csdn.net/2401_87944878/article/details/144408098https://blog.csdn.net/2401_87944878/article/details/144408098https://blog.csdn.net/2401_87944878/article/details/144408098https://blog.csdn.net/2401_87944878/article/details/144408098https://blog.csdn.net/2401_87944878/article/details/144408098https://blog.csdn.net/2401_87944878/article/details/144408098https://blog.csdn.net/2401_87944878/article/details/144408098

链表(C语言)-CSDN博客文章浏览阅读730次,点赞18次,收藏7次。用C语言实现数据结构中单链表和双链表的详细介绍https://blog.csdn.net/2401_87944878/article/details/144423576https://blog.csdn.net/2401_87944878/article/details/144423576https://blog.csdn.net/2401_87944878/article/details/144423576https://blog.csdn.net/2401_87944878/article/details/144423576https://blog.csdn.net/2401_87944878/article/details/144423576https://blog.csdn.net/2401_87944878/article/details/144423576https://blog.csdn.net/2401_87944878/article/details/144423576

基本功能实现

1)定义,初始化栈

栈的底层逻辑是顺序表,所以可以直接使用顺序表的初始化。

typedef int SDateType;

typedef struct Stack
{
	SDateType* a;
	int size;
	int capacity;
}Stack;

//栈的初始化
void StackInit(Stack* ps)
{
    assert(ps);
	ps->capacity = 4;
	ps->a = (SDateType*)malloc(sizeof(SDateType)*(ps->capacity));
	if (ps->a == NULL)
		perror("malloc failed!");

	ps->size = 0;
}

2)入栈

向栈顶添加元素,ps->size就是栈顶位置的下标;

//入栈
void StackPush(Stack* ps,  SDateType x)
{
    assert(ps);
	//判断空间够不够
	if (ps->capacity == ps->size)
	{
		ps->capacity *= 2;
		SDateType* new = (SDateType*)realloc(ps->a,sizeof(SDateType) * (ps->capacity));
		if (new == NULL)
			perror("realloc failed!");

		ps->a = new;
	}
	//入栈
	ps->a[ps->size] = x;
	ps->size++;
}

3)出栈

出栈不需要对栈顶元素进行处理,只需要将栈内元素个数-1即可,将栈顶元素看作无效数据;

//出栈
void StackPop(Stack* ps)
{
	assert(ps);
	assert(ps->size);

	ps->size--;
}

4)获得栈顶元素

//获得栈顶元素
SDateType StackTop(Stack* ps)
{
	assert(ps->a);
	assert(ps->size);

	return ps->a[ps->size - 1];
}

5)获得栈中有效元素个数

//获得栈中有效元素个数
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->size;
}

6)检测栈是否为空

//检测栈是否为空
bool IsStackEmpty(Stack* ps)
{
	assert(ps);
	if (ps->size == 0)
		return true;

	return false;
}

7)销毁栈

将malloc的空间释放,将顺序表中的变量制空。

//栈的销毁
void StackDestory(Stack* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

数据结构之队列 

定义

队列:也是一种特殊的线性表,其特点是只允许在一端(队尾)进行插入,另一端(队头)进行删除。队列的数据结构必须遵循先入先出(先进入的先出来原则。就好比车辆进站加油,先进入的车会先出来。

入队:向队尾添加元素;

出队:将队头的元素删去;

实现方式

与栈相同,队列也有两种实现方式;

1)顺序表实现,用顺序表可以直接找到队尾,进行入队,但是在出队的时候将队头元素删除后,要将后面元素整体向前移动,效率低

2)链表实现,用链表实现的时候,只要记录了尾节点,头节点就可以直接对队列进行入队和出队操作,链表实现的效率更高,此处以链表实行为例。

基本功能实现

1)定义,初始化队列

定义两个结构体,1)链表;2)用于记录头节点,尾节点及链表长度的结构体。

//定义队列
typedef int QDateType;

typedef struct QueNode
{
	QDateType date;
	struct QueNode* next;
}QueNode;

typedef struct Queue
{
	QueNode* front;
	QueNode* tail;
	int size;
}Queue;



//队列的初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->front = pq->tail = NULL;
	
	pq->size = 0;
}

2)入队

向队尾添加元素;

//入队
void QueuePush(Queue* pq, QDateType x)
{
    assert(pq);
	//创建新节点
	QueNode* newnode = (QueNode*)malloc(sizeof(QueNode));
	newnode->date = x;
	newnode->next = NULL;

	if (pq->front == NULL)
		pq->front = pq->tail = newnode;
	else
	{
		pq->tail->next = newnode;
		pq->tail = pq->tail->next;
	}
}

3)出队

将队头元素删去。

//出队
void QueuePop(Queue* pq)
{
    assert(pq);
	//记录队头
	QueNode* del = pq->front;
	pq->front = pq->front->next;

	free(del);
	del = NULL;
}

4)获得队列头部元素

//获得队列头部元素
QDateType QueTop(Queue* pq)
{
	assert(pq);
	assert(pq->size);

	return pq->front->date;
}

5)获得队尾元素

//获得队尾元素
QDateType QueTail(Queue* pq)
{
	assert(pq);
	assert(pq->size);

	return pq->tail->date;
}

6)队列元素个数

//获得队列元素个数
int QueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

7)队列是否为空

//判断队列是否为空
bool IsQueueEmpty(Queue* pq)
{
	assert(pq);
	if (pq->size == 0)
		return true;

	return false;
}

8)销毁队列

//销毁队列
void QueDestory(Queue* pq)
{
	assert(pq);
	//要销毁队列的每一个元素
	while (!IsQueueEmpty)
	{
		QueuePop(pq);
	}
	pq->front = pq->size = NULL;
}

栈和队列练习

1.1 有效括号

20. 有效的括号 - 力扣(LeetCode)

用栈的先入后出性质

遍历字符串,对于左括号入栈,当遇到右括号的时候,出栈,将出栈元素和左括号进行对比,看是否配对。

//有效括号
bool isValid(char* s) {
	Stack sta;
	StackInit(&sta);

	char* cur = s;
	while(*cur!='\0')
	{
		//判断是否是左括号
		if ((*cur) == '(' || (*cur) == '{' || (*cur) == '[')
		{
			StackPush(&sta, *cur);
			cur++;
		}
		//将左括号和右括号进行对比
		else
		{
			if (IsStackEmpty(&sta))
				return false;

			char left = StackTop(&sta);
			StackPop(&sta);  //取出栈顶元素
			if ((left == '(' && (*cur) != ')') ||
				(left == '{' && (*cur) != '}') ||
				(left == '[' && (*cur) != ']'))
				return false;

			cur++;
		}
	}
	if(!IsStackEmpty(&sta))
		return false;   //栈中还有元素

	return true;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

B站pwn教程笔记-1

因为没有垃圾处理机制,适合做编译,不会有堵塞 c语言市场占有率还是比较高的。 Windows根据后缀识别文件,linux根据文件头识别 55:16 编译过程 一步:直接gcc编译.c文件 这只是其中的一些步骤 gcc -S 转变为汇编。但其实这时候还…

jQuery小游戏

jQuery小游戏(一) 嘻嘻,今天我们来写个jquery小游戏吧 首先,我们准备一下写小游戏需要准备的佩饰,如果:图片、音乐、搞怪的小表情 这里我准备了一些游戏中需要涉及到的图片 游戏中使用到的方法 eval() 函…

Batch Normalization学习笔记

文章目录 一、为何引入 Batch Normalization二、具体步骤1、训练阶段2、预测阶段 三、关键代码实现四、补充五、参考文献 一、为何引入 Batch Normalization 现在主流的卷积神经网络几乎都使用了批量归一化(Batch Normalization,BN)1&#xf…

JavaSec系列 | 动态加载字节码

视频教程在我主页简介或专栏里 目录: 动态加载字节码 字节码 加载远程/本地文件 利用defineClass()直接加载字节码 利用TemplatesImpl加载字节码 动态加载字节码 字节码 Java字节码指的是JVM执行使用的一类指令,通常被存储在.class文件中。 加载远程…

第十四讲 JDBC数据库

1. 什么是JDBC JDBC(Java Database Connectivity,Java数据库连接),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库,并使用SQL语句来完成对数据库中数据的查询、新增、更新和删除等操作…

JVM面试题解,垃圾回收之“分代回收理论”剖析

一、什么是分代回收 我们会把堆内存中的对象间隔一段时间做一次GC(即垃圾回收),但是堆内存很大一块,内存布局分为新生代和老年代、其对象的特点不一样,所以回收的策略也应该各不相同 对于“刚出生”的新对象&#xf…

电脑如何访问手机文件?

手机和电脑已经深深融入了我们的日常生活,无时无刻不在为我们提供服务。除了电脑远程操控电脑外,我们还可以在电脑上轻松地访问Android或iPhone手机上的文件。那么,如何使用电脑远程访问手机上的文件呢? 如何使用电脑访问手机文件…

ThinkPHP 8模型与数据的插入、更新、删除

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…

【MySQL】数据库基础知识

欢迎拜访:雾里看山-CSDN博客 本篇主题:【MySQL】数据库基础知识 发布时间:2025.1.21 隶属专栏:MySQL 目录 什么是数据库为什么要有数据库数据库的概念 主流数据库mysql的安装mysql登录使用一下mysql显示数据库内容创建一个数据库创…

【线性代数】基础版本的高斯消元法

[精确算法] 高斯消元法求线性方程组 线性方程组 考虑线性方程组, 已知 A ∈ R n , n , b ∈ R n A\in \mathbb{R}^{n,n},b\in \mathbb{R}^n A∈Rn,n,b∈Rn, 求未知 x ∈ R n x\in \mathbb{R}^n x∈Rn A 1 , 1 x 1 A 1 , 2 x 2 ⋯ A 1 , n x n b 1…

高等数学学习笔记 ☞ 微分方程

1. 微分方程的基本概念 1. 微分方程的基本概念: (1)微分方程:含有未知函数及其导数或微分的方程。 举例说明微分方程:;。 (2)微分方程的阶:指微分方程中未知函数的导数…

HarmonyOS基于ArkTS卡片服务

卡片服务 前言 Form Kit(卡片开发框架)提供了一种在桌面、锁屏等系统入口嵌入显示应用信息的开发框架和API,可以将应用内用户关注的重要信息或常用操作抽取到服务卡片(以下简称“卡片”)上,通过将卡片添加…

Java复习第四天

一、代码题 1.相同的树 (1)题目 给你两棵二叉树的根节点p和q,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p[1,2,3],q[1,2,3] 输出:true示例 2: 输…

全面了解 Web3 AIGC 和 AI Agent 的创新先锋 MelodAI

不管是在传统领域还是 Crypto,AI 都是公认的最有前景的赛道。随着数字内容需求的爆炸式增长和技术的快速迭代,Web3 AIGC(AI生成内容)和 AI Agent(人工智能代理)正成为两大关键赛道。 AIGC 通过 AI 技术生成…

新能源汽车充电桩选型以及安装应用

摘要:随着当前经济的不断发展,国家的科技也有了飞速的进步,传统的燃油汽车已经不能适应当前社会的发展,不仅对能源造成巨大的消耗,还对环境造成了污染,当前一种新型的交通运输工具正在占领汽车市场。在环境问题和能源问题愈发严重的当今社会,节能减排已经成为全世界的共同课题,…

一个vue项目npm install失败的问题解决方案

vue的项目一直是史上最难的最烦的问题,今天给别人做毕设单子想在gitee上拉项目二开的时候,由于很久没写过vue项目已经生疏了,在拿到项目之后我还是例行完成最常见的步骤: 1、npm init -y 初始化 2、npm install 用npm把这个项目…

计算机网络 (55)流失存储音频/视频

一、定义与特点 定义:流式存储音频/视频是指经过压缩并存储在服务器上的多媒体文件,客户端可以通过互联网边下载边播放这些文件,也称为音频/视频点播。 特点: 边下载边播放:用户无需等待整个文件下载完成即可开始播放…

UE求职Demo开发日志#6 测试用强化页面UI搭建

1 反向实现思路设计 先看最终效果: 先做了一个大致的分区,右侧的上半部分用来显示数据,下半部分用来强化和显示需要的材料,至于这个背景设定上强化应该叫什么,。。。。,还没定,反正应该不叫强…

python学opencv|读取图像(四十一 )使用cv2.add()函数实现各个像素点BGR叠加

【1】引言 前序已经学习了直接在画布上使用掩模,会获得彩色图像的多种叠加效果,相关文章链接为: python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖-CSDN博客 这时候如果更进一步,直接…

SpringCloudAlibaba 服务保护 Sentinel 项目集成实践

目录 一、简介1.1、服务保护的基本概念1.1.1、服务限流/熔断1.1.2、服务降级1.1.3、服务的雪崩效应1.1.4、服务的隔离的机制 1.2、Sentinel的主要特性1.3、Sentinel整体架构1.4、Sentinel 与 Hystrix 对比 二、Sentinel控制台部署3.1、版本选择和适配3.2、本文使用各组件版本3.…