C语言数据结构-----栈和队列(概念,代码实现及简单练习)

news2024/11/27 12:34:04

前言

本篇主要介绍栈和队列的相关知识,练习以及代码实现。
代码主要展示部分功能的实现。完整代码在gitee上查看。
链接: 栈和队列的完整代码实现

文章目录

  • 前言
  • 1.栈
    • 1.1 栈的概念及结构
    • 1.2 栈的实现
    • 1.3 栈的代码实现
      • 1.3.1 栈的初始化
      • 1.3.2 栈顶插入
      • 1.3.3 栈顶删除
      • 1.3.4 返回栈顶数据
      • 1.3.5 判断栈是否为空
      • 1.3.6 获取栈中有效元素个数
      • 1.3.7 销毁栈
      • 1.3.8 主函数测试
    • 1.4 栈的练习题
  • 2.队列
    • 2.1 队列的概念及结构
    • 2.2 队列的实现
    • 2.3 队列的代码实现
      • 2.3.1 队列的初始化
      • 2.3.2 队列的尾插
      • 2.3.3 队列的头删
      • 2.3.4 获取队列头部元素
      • 2.3.5 获取队列尾部元素
      • 2.3.6 检测队列是否为空
      • 2.3.7 获取队列中有效元素个数
      • 2.3.8 摧毁
      • 2.3.9 主函数测试
    • 2.4 队列的练习题


1.栈

1.1 栈的概念及结构

①栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
②压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
③出栈:栈的删除操作叫做出栈。出数据也在栈顶

在这里插入图片描述

1.2 栈的实现

栈的实现有两种方式
在这里插入图片描述

1.3 栈的代码实现

1.3.1 栈的初始化

void STInit(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;//top是什么?0?
}

在这里插入图片描述
所以有两种设计方案:
在这里插入图片描述

我们采用top=0的方案!

1.3.2 栈顶插入

void STPush(ST* pst, STDataType x)
{
	assert(pst);
//扩容
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	//插入
	pst->a[pst->top] = x;
	pst->top++;
}

1.3.3 栈顶删除

void STPop(ST* pst)
{
	assert(pst);
	// top为0不能减减
	assert(pst->top > 0);
	pst->top--;
}

1.3.4 返回栈顶数据

STDataType STTop(ST* pst)
{
	assert(pst);
	// 不为空
	assert(pst->top > 0);
	return pst->a[pst->top - 1];//表达式应该是(pst->top) - 1,表示栈顶元素的前一个元素
}

1.3.5 判断栈是否为空

bool STEmpty(ST* pst)
{
	assert(pst);

	if (pst->top == 0)
		return true;
	else
		return false;
}

1.3.6 获取栈中有效元素个数

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

1.3.7 销毁栈

void STDestroy(ST* pst)
{
	assert(pst);

	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}

1.3.8 主函数测试

int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	printf("%d ", STTop(&s));
	STPop(&s);
	printf("%d ", STTop(&s));
	STPop(&s);
	STPush(&s, 4);
	STPush(&s, 5);
	//    一     对     多
	// 入栈顺序  --  出栈顺序
	while (!STEmpty(&s))
	{
		printf("%d ", STTop(&s));
		STPop(&s);
	}
	printf("\n");

	return 0;
}

后进先出是相对的,具体要看代码
入栈数据只有一种,出栈顺序可以是多种。

1.4 栈的练习题

在这里插入图片描述

2.队列

2.1 队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头

在这里插入图片描述
在这里插入图片描述

2.2 队列的实现

在这里插入图片描述

2.3 队列的代码实现

2.3.1 队列的初始化

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

2.3.2 队列的尾插

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->val = x;
	newnode->next = NULL;

	if (pq->ptail == NULL)
	{
		pq->ptail = pq->phead = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

2.3.3 队列的头删

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	QNode* del = pq->phead;
	pq->phead = pq->phead->next;
	free(del);
	del = NULL;
	if (pq->phead == NULL)
		pq->ptail = NULL;

	pq->size--;
}

在这里插入图片描述

2.3.4 获取队列头部元素

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->phead->val;
}

2.3.5 获取队列尾部元素

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->ptail);

	return pq->ptail->val;
}

2.3.6 检测队列是否为空

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL;
}

2.3.7 获取队列中有效元素个数

int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

2.3.8 摧毁

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

2.3.9 主函数测试

int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);

	QueuePush(&q, 4);
	QueuePush(&q, 5);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}

	QueueDestroy(&q);
	return 0;
}

2.4 队列的练习题

在这里插入图片描述

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

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

相关文章

若依框架修改包名报错

1.首先看下报错截图 启动GateWay 2.这个是因为 我改了里面的包名就是下面 ruoyi改成screen爆了上面的问题 3.那么关键的来了,我测了下 改了core不管启动gateway还是modules里面任何一个都会爆打不开工具类的问题 ,我看了其他pom也没有引用core&#xff…

功能强大的国产API管理神器 Eolink,亲测好用

前言 大家好,我是小月,今天给大家讲讲最近很火的Eolink,一款功能强大且非常实用的国产 API管理工具。在我们日常的前端、后端开发测试过程中经常会用到API,特别是在大型项目中API管理工具也就必不可少。工欲善其事必先利其器&…

[模版总结] - 树的基本算法1 - 遍历

树结构定义 一种非线性存储结构,具有存储“一对多”关系的数据元素集合 种类 General Tree TrieB/B 树二叉树 满/完满/完全二叉树 完美BT : 除了叶子结点外所有节点都有两个字节点,每一层都完满填充完全BT: 除最后一层以外其他每一层都完美…

FaceBook登录提示密码错误的原因及解决方法

下面这一种类型的提示密码错误,大家首先能够想到的可能就是本身的账号密码有错误,但这个只代表其一。有一种情况的话,他可能根本不是账号或者密码的错误,他仅仅是因为注册的地方和登录的地方不太一样,也会造成这样的结…

【JavaEE初阶】IP协议简介

文章目录 前言🌴IP协议的概念🌳IP数据报🚩IPv4协议头格式🚩IPv6的诞生 🎍IP地址🚩IP地址的格式:🚩IP地址的分类🎈网络号与主机号的划分 🚩特殊的IP地址&#…

QGIS之十九矢量投影

效果 步骤 1、准备数据 2、Qgis矢量投影 Qgis工具箱中搜索“投影” 3、结果

算法笔记-第七章-栈的应用(未完成)

算法笔记-第七章-栈的应用 栈的基本常识栈的解释一栈的解释二 栈的操作序列合法的出栈序列可能的出栈序列补充知识点 后缀表达式(无优先级) 栈的基本常识 栈(Stack)是只允许在一端进行插入或删除操作的线性表。 栈的解释一 栈的…

Vue dev-tools的安装

安装 Vue 开发者工具,装插件调试Vue应用 1.通过谷歌应用商店来进行安装(国外网站) 2.极简插件: 搜索 Vue -> 下载解压 -> 浏览器扩展模式打开,开发者模式 -> 将解压的CRX文件拖拽安装 -> 插件详情 &…

YOLOV8目标识别——详细记录从环境配置、自定义数据、模型训练到模型推理部署

一、概述 Yolov8建立在Yolo系列历史版本的基础上,并引入了新的功能和改进点,以进一步提升性能和灵活性。Yolov8具有以下特点: 高效性:Yolov8采用了新的骨干网络、新的Ancher-Free检测头和新的损失函数,可在CPU到GPU的…

在SpringBoot中使用EhCache缓存

在使用EhCache缓存之前,我们需要了解的是EhCache缓存是啥? Ehcache的概述 Ehcache是一个开源的Java缓存框架,用于提供高效的内存缓存解决方案,他可以用于缓存各种类型的数据,包括对象,查询结果&#xff0…

软件测试行业趋势分析

1 绪论 本文先对互联网对时代和社会变革进行了论述,然后再由互联网时代对软件工业模式变革进行了介绍,最后引出附属于软件工业的测试行业在新形势下的需求变化,并对趋势进行了分析,并最终给出了相关的从业人员的职业发展建议。 …

3DMAX建模基础教程:实例与复制

3D Studio Max,或称3DMAX,是一种专业的三维计算机图形软件,被广泛应用于电影、电视、游戏开发等领域。以下是一份关于3DMAX建模基础教程的实例与复制的详解。 3D模型实例化 实例化是一种重复使用相同对象的技术,而无需每次都创建…

搭建网站选择弹性云服务器

​ 弹性云服务器已成为建站的首选方案,弹性云服务器并从成本、灵活性、可扩展性和安全性等多个角度进行分析。 一、成本控制弹性云服务器以其优势的弹性计费模式,在建站初期成本控制中占据了重要地位。与传统的物理服务器相比,弹性云服务器可…

深度对话:以实在RPA Agent智能体安全机制破解LLM应用谜题

AI大模型席卷全球,为各个行业带来了颠覆式创新机遇,同时也打开了未知的潘多拉魔盒。随着大语言模型能力的不断增强和适用范围延伸,大模型本身带来的隐私泄漏、数据安全等问题越发成为各大厂商关注的核心,引发了各界更多的思考与发…

软件测试 —— 常见的自动化测试架构!

一个自动化测试架构就是一个集成体系,其中定义了一个特殊软件产品的自动化测试规则。这一体系中包含测试功能函数库、测试数据源、测试对象识别标准,以及各种可重用的模块。这些组件作为小的构建模块,被组合起来代表某种商业流程。自动化测试…

组件库篇 | EUI | 快速上手

组件库篇 | EUI | 快速上手 导入组件库 仅需三个步骤便可以导入组件库: 进入main.cpp所在目录,将EUI文件夹复制到该目录下 双击sln文件使用vs打开项目,右键项目名-添加-新建筛选器,命名为EUI 将第1步导入的EUI文件夹拖入到第2步…

做C语言的编程题总是想骂人怎么办?

做C语言的编程题总是想骂人怎么办? 可能C语言的编程题难住了您吧,导致情绪激烈不平静,那么做C语言的编程题可以顺利-些吗? 当然有一些方法可是现实此目标的:最近很多小伙伴找我,说想要一些C语言的资料,然后我根据自己…

K8S的基础知识

K8S的意义与入门 专有名词 容器:包含了运行一个应用程序所需要的所有东西,包括:代码、运行时、各种依赖和配置。pod:K8s调度的最小单元,包含一个或多个容器。一个容器组中的容器具有紧密耦合性,共享资源,存储空间和IP。即同一个容器组中的容器可以通过localhost:xxx访问…

【C++初阶(八)】C/C++内存管理详解

本专栏内容为:C学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C 🚚代码仓库:小小unicorn的代码仓库&…

C 语言指针怎么理解?

今日话题,C 语言指针怎么理解?让我用更简洁的方式来表达这个内容:就像桌面上的快捷方式一样,指针也可以有多层引用。我们可以将指针比作快捷方式的图标,快捷方式可以指向游戏(普通指针)&#xf…