数据结构--队列(图文)

news2025/1/17 9:08:11

队列是一种特殊的线性表,其核心特点是先进先出。

概念及特点:

概念

队列是一种只允许在一端进行插入数据操作,在另一端进行删除数据操作的线性表。进行插入操作的一端被称为队尾(Tail 或 Rear),进行删除操作的一端被称为队头(Head 或 Front)。在日常生活中,我们可以将队列比作排队等候的场景,排在前面的人会先得到服务,新来的人则排在队尾等待。
在这里插入图片描述

特点:

  1. 先进先出(FIFO):队列的基本操作是入队和出队。入队操作是在队尾插入一个元素,而出队操作是从队头删除一个元素。这意味着最先进入队列的元素将最先被移除。

  2. 操作受限:与普通的线性表不同,队列的操作是受限制的。只能在队尾添加元素,只能在队头删除元素。

  3. 两种实现方式:队列可以通过数组或链表来实现。使用数组实现时,可能会遇到数组空间受限的问题,但可以通过循环队列的方式解决。使用链表实现时,可以动态地分配内存,但可能会有额外的内存开销。

  4. 动态变化:队列是一种动态的数据结构,其大小可以根据需要动态变化。在入队和出队操作时,队列的大小会相应地增加或减少。

  5. 应用广泛:队列在计算机科学中有广泛的应用,如广度优先搜索、任务调度、缓冲处理、线程同步等。

队列的操作

  • 初始化:创建一个空队列。

  • 入队:将一个元素添加到队列的末尾,即队尾。

  • 出队:从队列的开头,即队首,移除元素并返回该元素的值。

  • 返回队首元素:返回队列中的第一个元素的值,但不从队列中删除该元素。

  • 返回队尾元素):返回队列中的末尾元素的值,但不从队列中删除该元素。

  • 获取队列元素个数:返回队列中的末尾元素的值,但不从队列中删除该元素。

  • 判断队列是否为空: 检查队列中是否没有任何元素。

  • 销毁队列:释放队列所占用的存储空间,使得队列不再存在。

队列的应用

队列的应用场景包括但不限于:

  • 打印机任务队列:打印机按照任务进入队列的顺序进行打印,确保了公平性和先到先服务的原则。

  • 网络请求处理:服务器使用队列来管理并响应客户端的请求,保证了请求按照到达顺序被处理。

  • 生产线作业:在生产线上,队列模型用于管理产品的生产流程,确保每个产品都能按照顺序经过各个加工阶段。

  • 消息队列:在消息传递系统中,消息被放入队列,然后由消费者按照顺序处理,支持异步消息处理和负载均衡。

  • 任务队列:在Web服务器和后台处理系统中,任务队列用于管理和调度异步任务,如发送电子邮件、处理图像等。

  • 优先级队列:在需要优先处理的场景中,如紧急任务或高价值任务,使用优先级队列可以确保这些任务能够优先被执行。

队列的实现

这里我们使用链表来实现队列。

首先创建三个文件:

  • Queue.h —— 用于声明函数的头文件。
  • Queue.c —— 队列主要函数的实现。
  • test.c——测试队列。

队列节点的定义

这里和单链表结构一致。

// 链式结构:表示队列 
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

队列指针的定义

将队列的首尾指针封装成一个结构体,可以方便函数调用,统一接口。再使用一个整型size记录元素个数,利于其他函数功能实现。

// 队列的结构 
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

在这里插入图片描述

初始化

// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);//队列必须存在
	q->head = q->tail = NULL;
	q->size = 0;
}

销毁队列

创建指针循环遍历链表,每次记录下指针的下一个节点,释放指针指向的节点,指针指向下一个节点

// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
	while (q->head)//释放所有节点
	{
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

入队列(队尾插入)

  • 情况一:队列为空直接申请新节点给头节点和尾节点;
  • 情况二:队列不为空,将新节点接入尾节点后即可。
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)//判定是否申请成功
	{
		perror("newnode error\n");
		exit(1);
	}
	newnode->data = data;
	newnode->next = NULL;
 
	if (q->head == NULL)//对空队列入队的处理
	{
		q->head = q->tail = newnode;
	}
	else               //对非空队列入队的处理
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}
	q->size++;
}

出队列(队头删除)

  • 情况一:队列只有一个节点,直接释放即可;
  • 情况二:队列有多个节点,将头节点的下一个节点保存后释放头节点,在让头节点指向保存的节点。
// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->head);//队列不能为空
	if (q->head == q->tail)//对只有一个元素的队列的出队处理
	{
		free(q->head);
		q->head = q->tail = NULL;
	}
	else          //对存在多个元素的队列的出队处理
	{
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->size--;
}

获取队头元素

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->head);//队列不能为空
	return q->head->data;
}

获取队尾元素

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->head);
	return q->tail->data;
}

获取队列元素个数

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

队列判空

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

队列源码

Queue.h

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
 
// 链式结构:表示队列 
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;
 
// 队列的结构 
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;
 
// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

Queue.c

#include"Queue.h"
 
// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);//队列必须存在
	q->head = q->tail = NULL;
	q->size = 0;
}
 
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)//判定是否申请成功
	{
		perror("newnode error\n");
		exit(1);
	}
	newnode->data = data;
	newnode->next = NULL;
 
	if (q->head == NULL)//对空队列入队的处理
	{
		q->head = q->tail = newnode;
	}
	else               //对非空队列入队的处理
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}
	q->size++;
}
 
// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->head);//队列不能为空
	if (q->head == q->tail)//对只有一个元素的队列的出队处理
	{
		free(q->head);
		q->head = q->tail = NULL;
	}
	else          //对存在多个元素的队列的出队处理
	{
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->size--;
}
 
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->head);//队列不能为空
	return q->head->data;
}
 
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->head);
	return q->tail->data;
}
 
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}
 
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}
 
// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
	while (q->head)//释放所有节点
	{
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

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

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

相关文章

使用ChatGLM3自带的网页客户端

【图书推荐】《ChatGLM3大模型本地化部署、应用开发与微调》-CSDN博客 通过简单的代码领略一下ChatGLM3大模型_chatglm3 history怎么写-CSDN博客 除了我们上面使用自定义的gradio组件完成网页客户端的搭建&#xff0c;智谱AI的ChatGLM3在创建之初就本着“方便用户&#xff0c…

小韩厂涨乌托邦公式源码

小韩厂涨&乌托邦&公式源码已经测试通过,可以发布云平台自行编辑 DRAWGBK(C>0, RGB(50,60,250),RGB(17,21,89),0,11,0); H1:=MAX(DYNAINFO(3),DYNAINFO(5)); L1:=MIN(DYNAINFO(3),DYNAINFO(6)); P1:=H1-L1; 阻力:=L1+P1*7/8,COLORGREEN; 支撑:=L1+P1*0.5/8,COLORRED;…

java学习 - 消息中间件简介 + RabbitMQ下载安装

消息与消息中间件 消息是指应用之间传输的数据消息中间件是一个提供高性能高可靠的消息传输交换的平台 消息传递的方式 点对点通讯 - P2P 基于队列实现队列使异步通讯成为可能 发布订阅模式 - Pub/Sub 有个节点&#xff0c;称为主题消息发布者将消息发布到这个节点上订阅者…

spring boot(学习笔记第十一课)

spring boot(学习笔记第十一课) Session共享&#xff0c;JPA实现自动RESTful 学习内容&#xff1a; Session共享JPA实现自动RESTful 1. Session共享 Session共享面临问题 spring boot默认将session保存在web server的内存里面&#xff0c;会产生什么问题呢。 如上图所示&#…

web全屏api,实现元素放大全屏,requestFullscreen,exitFullscreen

全屏api 主要方法 document.exitFullscreen(); 退出页面全屏状态&#xff0c;document是全局文档对象 dom.requestFullscreen(); 使dom进入全屏状态&#xff0c;异步&#xff0c;dom是一个dom元素 dom.onfullscreenchange&#xff08;&#xff09;; 全…

阿里云centos7.9 挂载数据盘到 www目录

一、让系统显示中文 参考&#xff1a;centos7 怎么让命令行显示中文&#xff08;英文-&#xff1e;中文&#xff09;_如何在命令行中显示中文-CSDN博客 1、输入命令&#xff1a;locale -a |grep "zh_CN" 可以看到已经存在了中文包 2、输入命令&#xff1a;sudo vi…

51单片机第21步_将TIM0用作两个8位定时器同时将TIM1用作波特率发生器

本章重点讲解将TIM0用作两个8位定时器&#xff0c;同时将TIM1用作波特率发生器。 当定时器T0在方式3时&#xff0c;T1不能产生中断&#xff0c;但可以正常工作在方式0、1、2下&#xff0c;大多数情况下&#xff0c;T1将用作串口的波特率发生器。 1、定时器0工作在模式3框图&a…

智能制造 v3.13.14 发布,ERP、MES 更新

智能制造一体化管理系统 [SpringBoot2 - 快速开发平台]&#xff0c;适用于制造业、建筑业、汽车行业、互联网、教育、政府机关等机构的管理。包含文件在线操作、工作日志、多班次考勤、CRM、ERP 进销存、项目管理、EHR、拖拽式生成问卷、日程、笔记、工作计划、行政办公、薪资模…

惧怕人工智能不如拥抱人工智能,聊聊如何使用Spring AI框架快速开发大模型项目

自ChatGPT出现以来&#xff0c;技术圈子里人人自危&#xff0c;导致大家心态越来越浮躁&#xff0c;生怕努力学习来的技术最后被人工智能轻易替代变得一文不值。其实换个角度来说大家也不用过于担心&#xff0c;社会的向前发展&#xff0c;生产力工具的优化更迭导致效率的提升是…

着色器预热?为什么 Flutter 需要?为什么原生 App 不需要?那 Compose 呢?Impeller 呢?

依旧是来自网友的问题&#xff0c;这个问题在一定程度上还是很意思的&#xff0c;因为大家可能会想&#xff0c;Flutter 使用 skia&#xff0c;原生 App 是用 skia &#xff0c;那为什么在 Flutter 上会有着色器预热&#xff08;Shader Warmup&#xff09;这样的说法&#xff1…

(一)Docker基本介绍

部署项目的发展 传统部署适合需要最大性能和可靠性的场景&#xff0c;但在资源利用和管理方面有显著劣势。虚拟化部署提供了良好的资源利用率和隔离性&#xff0c;适用于需要灵活扩展和多租户环境的场景&#xff0c;但存在性能开销。容器部署在轻量级、可移植性和资源利用率方面…

甄选范文“论单元测试方法及应用”,软考高级论文,系统架构设计师论文

论文真题 1、概要叙述你参与管理和开发的软件项目,以吸你所担的主要工作。 2、结给你参与管理和开发的软件项目,简要叙述单元测试中静态测试和动态测试方法的基本内容。 3、结给你惨与管理和研发的软件项目,体阐述在玩测试过程中,如何确定白盒测试的覆盖标准,及如何组织实施…

NetSuite Amount正负符号在Saved Search和DataSet中的不同含义

近期在一个项目中碰到Amount取值的Bug&#xff0c;原因是我们的代码中数据源从Saved Search转为了DataSet&#xff0c;由于这个转换导致了Amount的正负值混乱。今天记录一下。 正负号原则 • Saved Search&#xff0c; Amount的正负需要考虑科目类型。 Amount字段根据科目类型…

⭐Ollama的本地安装⚡

先来逛一下咱们的主角Ollama的官网地址&#xff1a; Ollama 大概长这个样子&#x1f914; 因为本地系统的原因&#xff0c;文章只提供Widows的安装方式&#xff0c;使用Linux和Mac的大佬&#xff0c;可以自行摸索&#x1f9d0; 下载完成后就是安装了&#x1f355;&#xff0c…

使用Petalinux设计linux系统

文章目录 1.通过 Vivado 创建硬件平台&#xff0c;得到 hdf 硬件描述文件2.设置 Petalinux 环境变量3.创建 Petalinux 工程4.配置Petalinux 工程5.配置Linux内核6.配置Linux根文件系统7.配置设备树文件8.编译 Petalinux 工程9.制作BOOT.BIN启动文件10.制作SD启动卡 1.通过 Viva…

Linux Swap机制关键点分析

1. page被swap出去之后,再次缺页是怎么找到找个换出的页面? 正常内存的页面是通过pte映射找到page的,swap出去的page有其特殊的方式:swap的页面page->private字段保存的是:swap_entry_t通过swap_entry_t就能找到该页面的扇区号sector_t,拿到扇区号就可以从块设备中读…

Golang | Leetcode Golang题解之第208题实现Trie前缀树

题目&#xff1a; 题解&#xff1a; type Trie struct {children [26]*TrieisEnd bool }func Constructor() Trie {return Trie{} }func (t *Trie) Insert(word string) {node : tfor _, ch : range word {ch - aif node.children[ch] nil {node.children[ch] &Trie{…

物体识别桌颠覆传统,创新科技重塑感知体验!

随着科技的疾驰进步&#xff0c;设想一下&#xff0c;站在一张桌面前&#xff0c;你只需优雅地挥动手掌&#xff0c;桌面的物品便如魔法般消失或重现。这不再是科幻电影的幻想&#xff0c;而是当下真实可触的奇迹——物体识别桌。这一革命性的技术不仅颠覆了观众对世界的感知&a…

Spark SQL----ANSI Compliance

Spark SQL----ANSI Compliance 一、算术运算二、Cast2.1 Rounding in cast 三、存储分配四、Type coercion4.1 类型提升和优先级4.2 最不常见类型解析 五、SQL函数5.1 函数调用5.2 具有不同行为的函数 六、SQL操作符七、ANSI模式的有用函数八、SQL关键字(可选&#xff0c;默认禁…

特征工程的力量

为什么你应该使用逻辑回归来建模非线性决策边界&#xff08;使用 Python 代码&#xff09; 作为一名大数据从业者&#xff0c;复杂的机器学习技术非常具有吸引力。使用一些深度神经网络 (DNN) 获得额外的 1% 准确率&#xff0c;并在此过程中启动 GPU 实例&#xff0c;这让人非常…