数据结构——队列(C语言实现)

news2024/11/8 16:56:51

队列的概念与结构

队列是一种特殊的线性结构,数据只能在一端插入,数据也只能在另一端进行删除。插入数据的那一端称之为队尾,插入数据的动作称之为入队。删除数据的那一端称之为队头,删除数据的动作称之为出列。队列遵守的是FIFO原则(Frist In First Out),即先进先出原则。
在这里插入图片描述
队列具体实现结构比较灵活,只要遵循FIFO原则即可。顺序表的方式实现,虽然尾插数据方便,头删的代价较大,故不推荐。单链表的方式实现,头删数据方便,只需要添加一个记录尾结点的指针,进行尾插数据的效率也还可以。所以本篇文章将以单链表的方式来实现队列。

队列的实现

队列的定义

首先,我们需要定义的是链式结构的队列,即单链表为底层实现的。所以需要定义单链表结构来存储数据。然后,定义队列,队列里需要定义两个指向单链表的指针,一个是指向单链表头结点的指针,另一个则用来保存尾结点地址的指针。最后,还需定义一个记录当前队列元素个数的变量,用于遍历队列和判空。

typedef int QueueDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QueueDataType data;
}QueueNode;

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

初始化队列

首先,断言判断一下指针合法性。然后,需要将队列内两个指针变量初始化。最后,将记录队列有效元素个数的变量初始化一下。

// 初始化队列
void QueueInit(Queue* q)
{
	assert(q);

	//初始化
	q->head = q->tail = NULL;
	q->size = 0;
}

队列销毁

首先,断言一下指针有效性。然后,依次释放每个结点。最后释放最后一个结点时,把tail和head置空,size置零。

// 销毁队列
void QueueDestroy(Queue* q)
{
	assert(q);

	//释放结点
	while (q->head)
	{
		QueueNode* next = q->head->next;
		if (q->tail != q->head)
		{
			free(q->head);
			q->head = next;
		}
		else
		{
			//避免野指针
			free(q->head);
			q->head=q->tail = NULL;
		}
	}
	//手动置零
	q->size = 0;
}

队列判空

由于在定义队列时,增加了额外的记录当前有效数据个数的变量,所以这里直接返回该变量与0比较的值即可。

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* q)
{
	return q->size == 0;
}

数据入队

首先,依旧断言判断指针有效性。其次,就是动态开辟结点,并对新节点初始化。然后,进行头插操作,记得第一次插入时,需要单独判断两个指针同时指向新结点。最后,记得让tail指针指向最后一个结点和size++。
在这里插入图片描述

// 队尾入队列
void QueuePush(Queue* q, QueueDataType data)
{
	//断言判断指针有效性
	assert(q);

	//开辟结点
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newnode)
	{
		perror("malloc fail\n");
		return;
	}
	newnode->next = NULL;
	newnode->data = data;


	//插入数据
	//空队列插入数据
	if (q->head == NULL)
	{
		q->head = q->tail = newnode;
	}
	//非空队列插入数据
	else
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}

	q->size++;
}

数据出列

首先,当队列为空时,不能进行删除操作,所以断言判断一下是否为空队列。然后,就是头删链表的操作,需要注意的是当只剩一个结点时,对tail进行特殊处理避免野指针。最后,就是让记录有效元素的size–一下。
在这里插入图片描述

// 队头出队列
void QueuePop(Queue* q)
{
	assert(q);
	//空队列无法删除数据
	assert(!QueueEmpty(q));


	//只有一个数据
	if (q->head == q->tail)
	{
		free(q->head);
		q->head = q->tail = NULL;
	}
	else
	{
		//先保存下一个结点
		QueueNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}

	//记录当前数据个数
	q->size--;

}

获取有效数据个数

由于在定义队列时,定义了一个记录当前有效元素个数的变量,所以这里直接返回该变量当前的值即可。

// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
	assert(q);

	return q->size;
}

获取队头数据

直接返回第一个结点的data即可。

// 获取队列头部元素
QueueDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->head->data;
}

获取队尾数据

直接返回tail指针指向的链表存放的数据即可。

// 获取队列队尾元素
QueueDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->tail->data;

}

队列的特点

由于队列是FIFO的原则,这就类似于去食堂排队打饭,先排队的就一定先吃上饭。而队尾的就得等先排队的打完饭了,才有机会吃饭。所以队列无论是变入列变出列,还是全部入列后再出列,结果是一样的。这和栈的LIFO原则有些许不同。

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

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

相关文章

LeetCode 189.轮转数组

文章目录💡题目分析💡解题思路🚩思路1:暴力求解 --- 旋转k次🔔接口源码:🚩思路2:额外开数组🔔接口源码:🚩思路3:三段逆置📍算法设计🔔接口源码&am…

JavaWeb开发 —— Web入门

目录 一、Spring 二、SpringBootWeb快速入门 三、HTTP协议 1. 概述 2. 请求协议 3. 响应协议 四、Web服务器 - Tomcat 1. 介绍 2. 基本使用 3. 入门程序解析 一、Spring ① 官网:http://spring.io ② Spring 发展到今天已经形成了一种开发生态圈&…

2022 idea 从原型创建maven项目框架--以创建niif-processors为列

目录一、idea配置二、下载archetype-catalog.xml文件三、创建设置四、创建成功截图一、idea配置 在如下两张图片花圈的位置添加如下参数 -Dmaven.wagon.http.ssl.insecuretrue -Dmaven.wagon.http.ssl.allowalltrue -Dmaven.wagon.http.ssl.ignore.validity.datestrue 二、下载…

Qt Quick - 导航控件综述

Qt Quick - 导航控件综述一、概述二、StackView控件三、SwipeView控件四、TabBar控件五、TabButton控件一、概述 Qt Quick Controls提供了一系列导航模型。 控件功能Drawer可以用滑动手势打开和关闭的侧滑动面板StackView提供基于堆栈的导航模型SwipeView允许用户通过横向滑动…

面试官:谈谈你对TypeScript有什么了解

TypeScript 相关面试题1.说说你对 TypeScript 的理解?与 JavaScript 的区别是什么特性区别2.说说你对 TypeScript 中类的理解?应用场景?是什么使用方式继承修饰符私有修饰符受保护修饰符只读修饰符静态属性抽象类应用场景3.说说 typescript 的…

简单易用的公司网页模板,助您快速建站

在当今数字化时代,拥有一个高质量的公司网页是每个企业成功的关键。然而,对于那些没有技术专业知识的人来说,创建一个专业的网页可能是一项艰巨的任务。但是,现在有许多简单易用的公司网页模板可用于帮助您快速建站。 下面&#…

【CSS】文字溢出问题 ( 强制文本在一行中显示 | 隐藏文本的超出部分 | 使用省略号代替文本超出部分 )

文章目录一、文字溢出问题二、文字溢出处理方案三、代码示例一、文字溢出问题 在元素对象内部显示文字 , 如果文本过长 , 则会出现文本溢出的问题 ; 下面的示例中 , 在 150x25 像素的盒子中 , 显示 骐骥一跃,不能十步;驽马十驾,功在不舍; 一段话 , 明显…

【初识C++】(缺省参数和函数重载)

文章目录一、缺省参数1.缺省参数定义2.缺省参数分类2.1全缺省参数2.2半缺省参数二、函数重载1.函数重载概念2.构成重载的几种方式为什么会有函数重载及其原理一、缺省参数 1.缺省参数定义 缺省参数是在函数的声明中给定参数一个指定的值。 如果传参没有给定参数,那…

三百左右蓝牙耳机选哪个?300左右无线蓝牙耳机推荐

多数人消遣的方式一般是听听音乐玩玩游戏,想要更好的体验感最少不了的一定就是蓝牙耳机了,可对于大多数人来说,irpods之类的属实太贵了,所以更多人追求性价比,之前也买过不靠谱的耳机,用几天就坏了&#xf…

MySQL数据库:索引

一、索引简介 1.概念 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。 相当于是给数据库中的数据建立了一个目录,通过目录可以知道…

QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。

QT多线程5种用法第一种 主线程(GUI)第二种 子线程1继承自QThread头文件 movetothread4.h源文件 movetothread4.cpp子线程1对象的创建第二种 子线程2继承自QThread头文件源文件对象创建位置(销毁)第三种 子线程3继承自QThread头文件源文件对象的创建第四种…

基于matlab仿真机械手

一、前言该示例显示了处于主动立体视觉模式的操纵器。它说明了立体渲染属性的效果以及如何使用立体视觉 VRFIGURE 属性。仅当图形卡支持四缓冲 OpenGL 渲染并由图形卡驱动程序启用时,操纵器才会以活动立体视觉模式显示。请注意,只有当您使用带有主动快门…

Android 布局 Fragment

Android 布局 FragmentFragment出现的初衷生命周期onCreate()onPause()onAttach()onCreateView()onActivityCreated()onDestroyView()onDetach()您可能还想扩展几个子类,而非 Fragment 基类:DialogFragmentListFragmentPreferenceFragmentCompat同系列文…

2.3.2单链表的插入删除

按位序插入(带头结点) 将第i-1个结点的指针指向第i个结点。 头节点看作是第0个结点。 s->datae //设定s指针的数据域为e s->nextp->next //将p指针指向的位置赋值给s指针指向的位置 p->nexts //再将s的数据域赋值给p指针指向的位置…

浅析分布式理论的CAP

大家好,我是易安! 今天让我们来聚焦于分布式系统架构中的重要理论——CAP理论。在分布式系统中,可用性和数据一致性是两个至关重要的因素,而CAP理论就是在这两者之间提供了一种权衡的原则,帮助我们在设计分布式系统时进…

MATLAB基于BP神经网络的光伏发电太阳辐照度预测(源码链接在文末)

光伏发电功率主要受太阳辐照度影响,所以准确预测太阳辐照度对光伏功率预测十分重要。程序采用小波分解先对辐照度数据进行分解,然后再用bp神经网络对分解的辐照度数据分别预测,再组合作为最后的预测结果。 人工神经网络(Artificial Neural …

研0进阶式学习---数据库1

目录Excel和数据库数据库的分类数据库的举例数据库基本结构数据库管理系统xampp、Navicat、MySQL基础知识与界面展示数据库基本连接步骤Excel和数据库 Excel和数据库都是用来存储数据的工具,但它们有以下区别和联系: 区别: 数据类型&#…

Java实现内网穿透

使用场景 1、当公司的一些系统功能使用了第三方服务时,通常第三方会回调我们的接口。在对接阶段,为了方便debug,我们肯定希望能回调到我们本地电脑上来。 2、当你在公司想访问部署在家里电脑的服务或者文件时。 3、当你的外地同事想访问你…

搭建nginx反向代理实现动静态分离

搭建nginx反向代理实现动静态分离一、实现高可用动静分离二 实验步骤2.1 安装nginx和开启路由转发2.2 实现lvs负载均衡2.3 实现动态网页功能2.4 实现nginx反向代理2.5 重启服务网页查看一、实现高可用动静分离 1、部署目的 ①用户访问业务时访问虚拟ip由lvs负责转发请求到业务…

LAMP及论坛搭建

1.编译安装apache 关闭防火墙,将安装Apache所需软件包传到/opt目录下 systemctl stop firewalld.service setenforce 0[rootlocalhost opt]# lsapr-1.6.2.tar.gz apr-util-1.6.0.tar.gz httpd-2.4.29.tar.bz2安装环境依赖包 yum -y install gcc gcc-c make pc…