c语言----队列

        很久没有写文章了。因为放假了嘛,给自己稍微放松了一下,所以最近的更新很慢。呜呜下一次一定改。然后咧。今天我想与大家分享的是队列。虽然这个知识点我们应该在讲了堆的实现就应该写的,但是后面忘了,以为自己是写了的。但是昨天看了看自己写的目录才发现自己忘了写队列了。所以今天把队列补上,并且当我们写了队列后我们会写队列与堆的相互实现。

队列的含义

        大家如果一直有在看我的文章的话可能已经了解了队列的含义了,但按照规矩我还是向大家解释一下队列的含义。队列咧。就像我们排队买奶茶一样。先进行排队的人可以先买后进行排队的人后买,我们大家都遵守的规则,然后队列也遵守这个规则。就好比我们的堆是后进先出一样。队列必须遵守这个。还有就是队列他只能头删和尾插。当然还有一些其他的基本上做比如说什么判空或者返回头元素之类的。那么接下里我们就来康康实现队列需要怎么搞。

实现队列

     创建结构体

       我们都说了,队列与堆可以相互出现,其实就代表他们的大体结构是差不多的。就只需要注意一下他们的定义的区别就可以了。那么我们应该也会要像他们一样先创建一个结构体来储存数据。但是我们创建结构体又不能指向开始一样只创建一个结构体。因为如果我们只创建一个结构体的话,我们需要数据节点为头节点,还需要再一个数组的个数还需要一个尾节点。然后还有指向的一个数据。如果都放在一个这个里面的话会比较麻烦,但是我们可以将头节点和尾节点直接单独拎出来。但是我们创建的结构里面的数据还是以最开始的节点为基准。大家可以先看一下我的代码是怎么样的:

typedef int QDateType;//队列存储数据类型

typedef struct QueueNode //队列元素节点
{
	QDateType val;//队列的元素个数
	struct QueueNode* next;//指向的下一个节点
}QueueNode;

typedef	struct Queue //队列
{
	QueueNode* head;//头节点
	QueueNode* tail;//尾节点
}Queue;

5c9d1e95af7d4a5f9884c89ba6e34443.png

        大家可以稍微看一下,我这个可能会比较抽象,但确实就像这样子。就好像创建了一个结构体,然后在他结构体里面再分化一下。 

队列的初始化

       对于队列的初始化,这样就很是很简单的,因为我们只需要将它的头节点和尾节点置为空就可以了。

void QueueInti(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}
队列的销毁

       相较于队列的初始化,队列的销毁就相对会麻烦一点。因为我们首先需要判断是否为空指针。然后再创建一个指针为头指针,依次销毁置空。然后再将头尾节点置为空就结束了。虽然也是很简单的,但是相较于初始化确实多了几行代码。

void QueueDestory(Queue* pq)
{
	assert(pq); //防止pq为空指针
	QueueNode* cur = pq->head;//创建一个零时节点以免对代码实现干扰
	while (cur)
	{//依次销毁,并且换到下一个
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->tail = pq->head = NULL;//头尾置为空
}
队列的入队列 

      我们在前面说我们队列是先进先出的,那么入队列肯定也是依次从头节点开始进入。所以我们对入队列就是需要开辟一个新的节点来存储数据。然后将他放在尾节点的后面然后将尾节点移位,那么这个头插就结束了。但是我们还需要思考的是并不是我们每一次使用开始队列就有数据了。那我们是不是需要区分一下,如果对于你开始里面没有数据应该怎么处理?就是当头节点和尾节点都是同一个的时候,还没有数据的时候。那么我们是不是应该让头节点和尾节点的同时置于相同的数据。因为这个时候我们头和尾节点是相同的呀。所以这也是我们需要考虑的一点。

void QueuePush(Queue* pq, QDateType x)
{
	assert(pq); //防止pq为空指针

	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));//创建新节点存放数据
	if (NULL == newNode)//判断是否创建好了
	{
		printf("malloc error\n");
		exit(-1);
	}
	newNode->val = x;
	newNode->next = NULL;//开辟一个新节点存储数据

	if (pq->tail == NULL)//判断是否为空队列
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}
队列的出队列

       我们在前面实现了尾插后,接下来就应该实现头删了。既然是头删,那么我们是不是要思考一下。假如只有一个指针的话,就是例如我刚插入一个之后,我就立马删除了。已经有很多个元素了,我再删除这两种区别。所以我们就需要分别的对待这两件事情。大家想一想,如果只有一个指针的话,我们是不是只需要将头和尾直接置为空就可以了?因为只有一个节点嘛,然后我删除一个节点,那是不是周围空了?所以就只需要将头和尾置空一下就好了。然后还有就是正常情况下,我们不能直接将头删掉,如果删掉的话是不是就不能找到下一个节点了?所以我们正常的情况下需要创建一个临时节点,然后再来删除。

void QueuePop(Queue* pq)
{
	assert(pq);//防止pq为空指针
	assert(pq->head && pq->tail); //防止队列为空队列
	if (pq->head->next == NULL)//假如只有一个节点的话,就全部置为空
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else//有多个节点就创建一个零时节点然后来释放置空
	{
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
队列的头元素

        对于队列的取头元素这是比较简单的,因为我们在最开始创建的时候就已经写了一个头节点和尾节点了。只需要判断节点是否为空就可以了。

QDateType QueueFront(Queue* pq)
{
	assert(pq);//防止pq为空指针
	assert(pq->head && pq->tail); //防止队列为空队列

	return pq->head->val;
}
   队列的判空

       关于队列的判空呢其实也是比较简单的。如果当头节点和尾节点相同,并且为都为空的话,那么肯定就是空的队列了。当然我们还是需要判断指针是否为空。

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}
队列的元素个数

         对于判断队列的元素个数,我的这个方法其实是比较麻烦的,我是像在需要队列个数的时候重新执行一遍便利的过程,这样我们就可以得出元素的个数了。但是也可以在创建结构体的那个地方再加一个size反正就是一个计数的就可以了,那么如果当我们计数的为零,那么就说明是队列为空,并且对于我们计算元素个数也是很方便的,当然这也是另外一种的方法,我这里就先写我原本的遍历一遍就好了,大家如果感兴趣的话,后面可以尝试一下。

int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;//创建一个临时节点,更加方便操作
	int count = 0;
	while (cur)
	{
		cur = cur->next;
		count++;
	}
	return count;//返回个数
}

总结

       好了,上面就是关于队列的大部分使用方法了。当然还有很多对于这个的延伸,这就可能会用在后面的题目上。后面的面试题之类的。那可以多尝试一下练题,然后就能加深一下对队列的一些的相关知识的巩固。那么接下来来我就这样所有的代码给大家看一下。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

typedef int QDateType;

typedef struct QueueNode
{
	QDateType val;
	struct QueueNode* next;
}QueueNode;

typedef	struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;

void QueueInti(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

void QueueDestory(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->tail = pq->head = NULL;
}

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

	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newNode)
	{
		printf("malloc error\n");
		exit(-1);
	}
	newNode->val = x;
	newNode->next = NULL;

	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}

}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail);
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

QDateType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->val;
}

int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	int count = 0;
	while (cur)
	{
		cur = cur->next;
		count++;
	}
	return count;
}

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

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

相关文章

LLM - 词表示和语言模型

一. 词的相似度表示 (1): 用一系列与该词相关的词来表示 (2): 把每个词表示一个独立的符号(one hot) (3): 利用该词上下文的词来表示该词 (3): 建立一个低维度的向量空间&#xff0c;用深度学习方法将该词映射到这个空间里(Word Embedding) 二&#xff1a;语言模型 (1): 根…

基于 STM32 的智能睡眠呼吸监测系统设计

本设计的硬件构成&#xff1a; STM32F103C8T6单片机最小系统板&#xff08;包含3.3V稳压电路时钟晶振电路复位电路&#xff08;上电自复位&#xff0c;手动复位&#xff09;&#xff09;&#xff0c;心率传感器、气压传感器、液晶显示、按键、蜂鸣器、LED灯、蓝牙模块组合而成…

电传动无杆飞机牵引车交付用户

自2019年起&#xff0c;我们计划做电传动控制&#xff0c;先后做了电传动水泥搅拌罐车罐体控制&#xff08;国内首创&#xff09;&#xff0c;初步理解了电机控制的特点。 20-21年接着做了10t飞机牵引车控制&#xff0c;还是电液控制联合的&#xff0c;把越野叉车的行驶控制方…

Prompt的万能公式和优化技巧

文章目录 前言一、万能公式二、优化技巧1.设定角色2.设定目标和动机3.引导主观回答4.预设条件5.做强调6.思维链&#xff08;COT&#xff09;7.巧用定界符 前言 随着LLM的发展&#xff0c;能给我们带来很多方便&#xff0c;但是又引出了一个新的问题就是我们该如何使用他们&…

网络编程:UDP编程笔记

1.字节序的概念和转换 小端格式: 低位字节数据存储在低地址 大端格式: 高位字节数据存储在低地址 在主机上时为小端存储,在网络上时为大端,所以接收到数据时,要转为小端口 如下图: #include <arpa/inet.h> 发送者调用的函数: uint32_t htonl(uint32_t hostlong); //转…

复分析——第8章——共形映射(E.M. Stein R. Shakarchi)

第8章 共形映射(Conformal Mappings) The results I found for polygons can be extended under very general assumptions. I have undertaken this research because it is a step towards a deeper understanding of the mapping problem, for which not much has hap…

SpringBoot 启动流程二

SpringBoot启动流程二 我们首先查看构造方法 SpringApplication 我们发现这个构造方法还是在SpringApplication类里面 这个构造方法还是调用了自身的构造方法 传入了两个参数 第一个参数叫resourceLoader 传入的是一个资源加载器 要从外部读入东西 这个方法通过this关键字…

PhpStorm 2024 for Mac PHP集成开发工具

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff08;适合自己的M芯片版或Intel芯片版&#xff09;&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功3、打开访达&#xff0c;点击【文…

嵌入式底层系统了解

当裸机功能不复杂的时候&#xff0c;即类似与点亮一个LED灯&#xff0c;驱动LCD和OLED这样的模块&#xff0c;以及各位大学生的搭积木式的毕业设计(狗头保命&#xff09;&#xff0c;此时可以简单地分为硬件和软件层&#xff08;应用层),以及以中间层作为中间联系。 当需要实现…

音视频入门基础:H.264专题(7)——FFmpeg源码中 指数哥伦布编码的解码实现

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

【SpringCloud】Ribbon源码解析

ribbon是一个负载均衡组件&#xff0c;它可以将请求分散到多个服务提供者实例中&#xff0c;提高系统的性能和可用性。本章分析ribbon是如何实现负载均衡的 1、LoadBalanced 消费者在引入ribbon组件后&#xff0c;给http客户端添加LoadBalanced注解就可以启用负载均衡功能。Lo…

MATLAB贝叶斯线性回归模型案例

采用辛烷值数据集“spectra_data.mat”(任意数据集均可),介绍贝叶斯线性回归模型的构建和使用流程。 运行结果如下: 训练集预测精度指标如下: 训练集数据的R2为: 1 训练集数据的MAE为: 0.00067884 训练集数据的RMSE为: 0.00088939 测试集预测精度指标如下: 测试集数据的R2…

Python学习之小游戏--坦克大作战

今天跟视频学习了Python实现坦克大作战小游戏&#xff0c;挺有意思的&#xff0c;一起来玩吧~ 按空格发射子弹&#xff0c;上下左右键实现移动&#xff0c;ESC键无限复活。 import pygame,time,random from pygame.sprite import Sprite SCREEN_WIDTH800 SCREEN_HEIGHT500 BG…

如何改善提示词,让 GPT-4 更高效准确地把视频内容整体转换成文章?

&#xff08;注&#xff1a;本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 让我们来讨论一下大语言模型应用中的一个重要原则 ——「欲速则不达」。 作为一个自认为懒惰的人&#xff0c;我一直有一个愿望&#xff1a;完成视频制作…

typescript2-类的类型

/* 输出 吃饭 游泳 */ []( )继承与多态------------------------------------------------------------------------1. 子类继承父类特征子类 extends 父类2. 当需要父类参数传递时&#xff0c;用子类也可以&#xff0c;这就是多态/* 继承&#xff1a;子类继承父类 多态…

集团型企业组织架构复杂,业务线多,如何进行高效费用管控?

企业管理中流行这样一句话&#xff1a;“企业转型&#xff0c;财务先行”。对集团型企业而言&#xff0c;当今的发展形势下&#xff0c;通过财务战略全面转型、最终撬动企业价值提升&#xff0c;是一件难而正确的事情。 集团企业具有经营规模大、产业链多、分支机构多、地域跨度…

容器部署rabbitmq集群迁移

1、场景&#xff1a; 因业务需要&#xff0c;要求把rabbitmq-A集群上的数据迁移到rabbitmq-B集群上&#xff0c;rabbitmq的数据包括元数据&#xff08;RabbitMQ用户、vhost、队列、交换和绑定&#xff09;和消息数据&#xff0c;而消息数据存储在单独的消息存储库中。 2、迁移要…

中国算力网络市场发展分析

中国算力网络市场发展现状 算力涵盖计算、内存、存储等全方位能力&#xff0c;广泛分布于网络边缘、云计算中心、联网设备及转发节点。随着数字化技术革新&#xff0c;算力与网络正深度融合&#xff0c;推动“算网一体化”的演进。这一新型基础设施日渐凸显其重要性&#xff0c…

番外篇 | YOLOv8改进之即插即用全维度动态卷积ODConv + 更换Neck网络为GFPN

前言:Hello大家好,我是小哥谈。本文所做出的改进是在YOLOv8中引入即插即用全维度动态卷积ODConv和更换Neck网络为GFPN,希望大家学习之后能够有所收获~!🌈 目录 🚀1.基础概念 🚀2.网络结构 🚀3.添加步骤 🚀4.改进方法 🍀🍀步骤1:block.py文件修改…

Kamailio-Web管理页面Siremis的安装与部署

siremis 是针对于 Kamailio 的web管理接口&#xff0c;使用PHP书写&#xff0c;更新至2020年&#xff0c;相对不是太新但是是官方友链的 以下就采用 Ubuntu 22.04Siremis 5.8.0apache http server 2.4php7.0 如有疑问请参看官方指南 以下开始介绍操作步骤 安装apache2.4 we…