数据结构:队列(含源码)

news2024/11/23 13:12:29

目录

一、队列的概念和结构

二、队列的实现

 头文件

初始化

入队列和出队列

获取队头队尾元素

 队列有效数据数及队列判空

队列的销毁

完整源码

dl.h

dl.c


一、队列的概念和结构

    队列是一种只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出,进行插入操作的一端称为队尾,进行删除操作的一端称为队头,与栈刚好相反,栈时先进后出,队列是先进先出。

二、队列的实现

    队列和栈类似,都可以用链表和数组实现,不过有一点不同的是,队列用链表实现会更好一点,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低,这篇文章就用链表实现。

 头文件

    写入整个程序需要用到的头文件以及队列各个功能的函数名

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

// 链式结构:表示队列 
typedef struct QListNode 
{ 
 struct QListNode* _pNext; 
 QDataType _data; 
}QNode; 
 
// 队列的结构 
typedef struct Queue 
{ 
 QNode* _front; 
 QNode* _rear; 
}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);

    因为是基于链表实现所以这里需要写连个结构体,一个是队列各个节点的数据,另一个是能让队列中通过单个节点能够找到其余节点,第二个结构体用到了第一个结构体逻辑上也相当于将第一个结构体包含在内了。

初始化

    前后指针都置空,队列中元素数归0

void QueueInit(Queue* q)
{
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}

入队列和出队列

    入队列在队尾,出队列在队头

void QueuePush(Queue* q, QDataType data)
{
	QNode* new = (QNode*)malloc(sizeof(QNode));
	new->next = NULL;
	new->data = data;
	if (q->front == NULL)
	{
		q->front = q->rear = new;
	}
	else
	{
		q->rear->next = new;
		q->rear = q->rear->next;
	}
	q->size++;
}

    申请空间,输入数据,如果为首个数据,就要充当队头和队尾两个角色 ,如果不是,只要修改队尾就行了,接在旧的队尾上成为新的队尾,最后队列数据元素数+1。

void QueuePop(Queue* q)
{
	assert(q->front);
	QNode* a = q->front->next;
	free(q->front);
	q->front = a;
	q->size--;
}

     删除队头,让第二个数据担任新的队头,队列数据元素数-1。

获取队头队尾元素

    这个就很简单,直接取数据就行了

QDataType QueueFront(Queue* q)//取队头
{
	assert(q->front);
	return q->front->data;
}
QDataType QueueBack(Queue* q)//取队尾
{
	assert(q->rear);
	return q->rear->data;
}

 队列有效数据数及队列判空

    取队列有效数据和取队头队尾元素一样,直接取数据就行了。

int QueueSize(Queue* q)
{
	assert(q->front);
	assert(q->size > 0);
	return q->size;
}

    队列的判空直接看有效数据是否为0就可以判断出

bool QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}

队列的销毁

    先把每个节点都销毁,再把队头指针和队尾指针置空,队列数据数归0

void QueueDestroy(Queue* q)
{
	while (q->front)
	{
		QNode* a = q->front->next;
		free(q->front);
		q->front = a;
	}
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}

完整源码

dl.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* front;
	QNode* rear;
	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);
 
bool QueueEmpty(Queue* q);

void QueueDestroy(Queue* q);

dl.c

#include"dl.h"
void QueueInit(Queue* q)
{
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}
void QueuePush(Queue* q, QDataType data)
{
	QNode* new = (QNode*)malloc(sizeof(QNode));
	new->next = NULL;
	new->data = data;
	if (q->front == NULL)
	{
		q->front = q->rear = new;
	}
	else
	{
		q->rear->next = new;
		q->rear = q->rear->next;
	}
	q->size++;
}
void QueuePop(Queue* q)
{
	assert(q->front);
	QNode* a = q->front->next;
	free(q->front);
	q->front = a;
	q->size--;
}
QDataType QueueFront(Queue* q)
{
	assert(q->front);
	return q->front->data;
}
QDataType QueueBack(Queue* q)
{
	assert(q->rear);
	return q->rear->data;
}
int QueueSize(Queue* q)
{
	assert(q->front);
	assert(q->size > 0);
	return q->size;
}
bool QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}
void QueueDestroy(Queue* q)
{
	while (q->front)
	{
		QNode* a = q->front->next;
		free(q->front);
		q->front = a;
	}
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}

     代码还是要自己一个一个的敲出来,这样才能加深对队列知识的理解。

    另外了解一下,实际中我们有时还会使用一种队列叫循环队列,生产者消费者模型时可以就会使用循环队列,环形队列可以使用数组实现,也可以使用循环链表实现。

 


    本篇的内容就到这里了,希望对各位有帮助,如果有错误欢迎指出。

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

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

相关文章

重生之我 学习【数据结构之顺序表(SeqList)】

⭐⭐⭐ 新老博友们&#xff0c;感谢各位的阅读观看 期末考试&假期调整暂时的停更了两个多月 没有写博客为大家分享优质内容 还容各位博友多多的理解 美丽的八月重生之我归来 继续为大家分享内容 你我共同加油 一起努力 ⭐⭐⭐ 数据结构将以顺序表、链表、栈区、队列、二叉树…

多米诺和托米诺平铺

有两种形状的瓷砖&#xff1a;一种是2 x 1的多米诺形&#xff0c;另一种是形如L的托米诺形。两种形状都可以旋转。 给定整数 n &#xff0c;返回可以平铺 2 x n 的面板的方法的数量。返回对 10^9 7 取模 的值。 平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同&#xff…

maven常用命令与常见问题汇总

文章目录 一、IDEA 下载依赖包源码报错Sources not found for:xxxx二、常用命令1、打包 一、IDEA 下载依赖包源码报错Sources not found for:xxxx 解决方案&#xff1a; 方案1、在 terminal 运行 mvn dependency:resolve -Dclassifiersources 命令 方案2、右键特定的pom文件…

论文概览 |《IJGIS》2024 Vol.38 issue4

本次给大家整理的是《International Journal of Geographical Information Science》杂志2024年第38卷第4期的论文的题目和摘要&#xff0c;一共包括8篇SCI论文&#xff01; 论文1 knowledge-constrained large language model interactable with GIS: enhancing public risk …

笔试题 day1

目录 快速io 统计2的个数 两个数组的交集 点击消除 快速io import java.util.*; import java.io.*;public class Main {public static PrintWriter out new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));public static Read in new Read();publ…

瑞_Linux防火墙相关命令_Windows远程连接虚拟机的服务失败_Linux防火墙端口开放

&#x1f64a; 前言&#xff1a;博主在学习使用虚拟机的过程中&#xff0c;常常碰到 Windows 远程连接虚拟机的服务失败的问题。比如想要在主机上连接虚拟机中的 MongoDB 服务的时候&#xff0c;服务器或者虚拟机一般都会默认开启防火墙&#xff0c;则会导致远程连接失败&#…

做一个能和你互动玩耍的智能机器人之七-接入对话和大模型

接入科大迅飞的语音识别&#xff1a; private void printResult(RecognizerResult results) {String text JsonParser2.parseIatResult(results.getResultString());String sn null;// 读取json结果中的sn字段try {JSONObject resultJson new JSONObject(results.getResult…

如何忽略已经提交到 Git 仓库中的文件

文章目录 前言一、确认文件是否已经被提交二、确认 .git 文件存在三、修改 .git/info/exclude 文件四、修改文件名五、提交和推送六、验证总结 前言 在日常开发中&#xff0c;我们常常会遇到这样的情况&#xff1a;不小心将不应追踪的文件提交到了 Git 仓库中&#xff0c;例如…

LabVIEW中的Reverse String函数与字节序转换

在LabVIEW中&#xff0c;数据的字节序&#xff08;也称为端序&#xff09;问题通常出现在数据传输和存储过程中。字节序可以分为大端&#xff08;Big-Endian&#xff09;和小端&#xff08;Little-Endian&#xff09;&#xff0c;它们分别表示高字节存储在低地址和低字节存储在…

培训第二十二天(mysql数据库主从搭建)

上午 1、为mysql添加开机启动chkconfig [rootmysql1 ~]# chkconfig --list //列出系统服务在不同运行级别下的启动状态注&#xff1a;该输出结果只显示 SysV 服务&#xff0c;并不包含原生 systemd 服务。SysV 配置数据可能被原生 systemd 配置覆盖。 要列出 systemd 服务…

2024.8.2(MySQL)

一、mysql 1、下载mysql软件包 [rootmysql ~]# yum -y install wget [rootmysql ~]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 2、解压 [rootmysql ~]# tar -xf mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 3、安装…

完美解决浏览器的输入框自动填入时,黄色背景问题,以及图标被遮住问题(最新)

用图说话↓↓↓ 首先用代码解决黄色背景问题&#xff0c;box-shadow颜色设置透明即可 :deep(input:-webkit-autofill) {box-shadow: 0 0 0 1000px transparent !important;/* 浏览器记住密码的底色的颜色 */-webkit-text-fill-color: #fff !important;/* 浏览器记住密码的字的…

【Linux 驱动】IMX6ULL input驱动

1. input子系统介绍 input 子系统分为 input 驱动层、input 核心层、input 事件处理层&#xff0c;最终给用户空间提供可访问的设备节点。 驱动层&#xff1a;输入设备的具体驱动程序&#xff0c;比如按键驱动程序&#xff0c;向内核层报告输入内容核心层&#xff1a;承上启下…

【docker】docker和镜像仓库

阿里云镜像仓库&#xff08;Aliyun Container Registry&#xff09;是阿里云提供的容器镜像存储和管理服务。它以Docker Registry协议为基础&#xff0c;为容器开发者提供了稳定可靠的镜像存储和分发服务。 使用阿里云镜像仓库&#xff0c;您可以将自己的Docker镜像推送到阿里…

lc209. 长度最小的子数组

题目&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 思路&#xff1a;…

非刚性ICP算法

非刚性ICP配准通过对V上的每个顶点v_i&#xff0c;利用仿射变换X_i来对模板网格进行变形。由此将V形变成为一个形变模板网格V^′&#xff0c;使得V^′与目标数据T的形状越接近越好&#xff0c;即V^′上的每个顶点在T上的对应点为该顶点在T中的最近点。该过程的目标函数如下&…

原生js: AI聊天功能, 仿照chatGPT问答功能

问: 现在我们需要一个ai聊天功能, 接口已经给出: 只要是message就是我们的数据, 是message_end就是结束信息, 其他的我们不需要管. 回答: 我们不使用传统的fetch请求这个接口, 而是使用sse, eventSource去请求, 当我们输入框回车 或者 点击元素, 获取到输入框中用户输入的值…

stm32入门学习10-软件I2C和陀螺仪模块

&#xff08;一&#xff09;I2C通信 &#xff08;1&#xff09;通信方式 I2C是一种同步半双工的通信方式&#xff0c;同步指的是通信双方时钟为一个时钟&#xff0c;半双工指的是在同一时间只能进行接收数据或发送数据&#xff0c;其有一条时钟线&#xff08;SCL&#xff09;…

MyBatis补充

控制类和dao层接口以及mapper中的xml是怎样的关联的&#xff1f; 在Mybatis中&#xff0c;控制类和dao层接口是通过mapper的xml文件进行连接的。 控制类调用dao层接口中的方法&#xff0c;通过接口实现进行访问数据库操作。dao层接口定义数据库操作的方法&#xff0c;提供给控制…

第6章>>实验7:PS(ARM)端Linux RT与PL端FPGA之间(通过Memory存储器进行通信和交互)《LabVIEW ZYNQ FPGA宝典》

1、实验内容 上一节实验里面介绍的Reg寄存器通道比较适合在PS端和PL端之间传递标量数据&#xff0c;也就是单个元素&#xff0c;如果要传递多个元素的数组或者连续数据流的话&#xff0c;Reg寄存器通道就不是很合适了。 本节实验我们向大家讲解如何借助Memory存储器通道在PS&am…