数据结构:7、队列

一、队列的概念与结构

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

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

二、队列的实现

1、队列的初始化与销毁

这个思路是,先创建一个节点用来存储数据,也就是一个单链表,而这里需要头和尾,也就是尾进头出,如1 2 3 4 5 6 7 这样进去,出去也是1 2  3 4 5 6 7,顺序不会改变,所以这里又定义了一个结构用来存储头和尾以及有效的数据,方便后续操作,初始化这里就是把头和尾指向空,当有数据进来时才指向新的节点,销毁就是把单链表释放销毁,而刚开始使用存储链表的头和尾的结构体,因为是局部变量,只需要把头和尾的指针置空,当函数销毁时,这个结构体也会销毁,代码如下。

typedef int QDataType;
// 链式结构:表示队列 
typedef struct QueueNode
{struct QueueNode* next;QDataType data;}QNode;// 队列的结构 
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
// 初始化队列 
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
// 销毁队列 
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、队列的入队与出队

这个队列是尾进头出,也就相当于尾插头删,但是需要考虑到链表中没有数据时的情况,也就是尾插时没有数据,会插入一个数据,第二个就是正常的尾插,而头删就需要考虑没有数据时,就直接释放了,代码如下。

// 队尾入队列 
void QueuePush(Queue* pq, QDataType data)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = data;newnode->next = NULL;if (pq->ptail == NULL){assert(pq->phead==NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}// 队头出队列 
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}

3、判断与获取首尾元素与队列内有效元素

这个就是利用之前创建的结构体可以判断下链表里有没有数据,如果有可以直接返回,之前定义的数据个数也就是可以直接看出链表有多少数据,判断也就可以直接判断有多少数据,但是不能在删除时不能忘记把数据个数减减。

// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size==0;
}

4、测试与测试结果

这个就是测试各个函数,也就是插入1 2 3 4 5 6 7然后读取下有几个数据,然后把尾部数据打印,利用之前写的判断函数也就可以直接用while函数去进行出队数据并且打印,然后队里数据全部出完后,再去取数据打印和删除,会直接报错,代码和测试结果如图。

#define _CRT_SECURE_NO_WARNINGS 1
#include "QL.h"void TestQueue()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);QueuePush(&q, 6);QueuePush(&q, 7);printf("size:%d\n", QueueSize(&q));printf("%d\n", QueueBack(&q));while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}printf("%d ", QueueFront(&q));QueuePop(&q);QueueDestroy(&q);
}int main()
{TestQueue();return 0;
}

三、代码

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "QL.h"void TestQueue()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);QueuePush(&q, 6);QueuePush(&q, 7);printf("size:%d\n", QueueSize(&q));printf("%d\n", QueueBack(&q));while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}printf("%d ", QueueFront(&q));QueuePop(&q);QueueDestroy(&q);
}int main()
{TestQueue();return 0;
}

QL.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "QL.h"// 初始化队列 
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}// 队尾入队列 
void QueuePush(Queue* pq, QDataType data)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = data;newnode->next = NULL;if (pq->ptail == NULL){assert(pq->phead==NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}// 队头出队列 
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size==0;
}// 销毁队列 
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;
}

QL.h

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio下运行java main 方法

方法一 修改项目的.idea中的gradle.xml文件&#xff0c;在GradleProjectSettings标签下添加一行代码 <option name"delegatedBuild" value"false" />方法二 main方法上右键选择Run ‘xxx’ with Coverage

【LeetCode: 2864. 最大二进制奇数 + 模拟 + 位运算】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Elastic Stack--05--聚合、映射mapping

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.聚合(aggregations)基本概念桶&#xff08;bucket&#xff09;度量&#xff08;metrics&#xff09; 案例 11. 接下来按price字段进行分组&#xff1a;2. 若想对所…

UE4案例记录

UE4案例记录&#xff08;制作3D角色显示在UI中&#xff09; 制作3D角色显示在UI中 转载自youtube视频 https://www.youtube.com/channel/UCC8f6SxKJElVvaRb7nF4Axg 新建项目 创建一个Actor 场景组件->摄像机组件->场景捕获组件2D&#xff0c;之后添加一个骨骼网格体…

使用helm部署clickhouse

&#xff08;作者&#xff1a;陈玓玏&#xff09; 前置条件 已安装 Kubernetes 集群&#xff1b; 已安装 Helm 包管理工具。 部署 1 添加 RadonDB ClickHouse 的 Helm 仓库 helm repo add ck https://radondb.github.io/radondb-clickhouse-kubernetes/ helm repo upd…

【LLMs+小羊驼】23.03.Vicuna: 类似GPT4的开源聊天机器人( 90%* ChatGPT Quality)

官方在线demo: https://chat.lmsys.org/ Github项目代码&#xff1a;https://github.com/lm-sys/FastChat 官方博客&#xff1a;Vicuna: An Open-Source Chatbot Impressing GPT-4 with 90% ChatGPT Quality 模型下载: https://huggingface.co/lmsys/vicuna-7b-v1.5 | 所有的模…

使用公式在Excel中指定列值的变化实现自动间隔着色(不是按照固定的行数)

如果你的文件很小&#xff0c;可以手工着色&#xff1b;但如果很大&#xff0c;就要借助公式来着色&#xff1b; 目的是什么&#xff0c;其中之一是&#xff1a;提升可读性。 一起往下看吧&#xff01;&#xff01; 如果你想要根据Excel某列中值的变化来间隔着色&#xff0c;…

一台服务器部署两个独立的mysql实例

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

python--类与面向对象-2

一、对象在文本中的输出 class Person: def __init__(self,name,agg,live_value,money): self.namename self.aggagg self.live_valuelive_value self.moneymoney def describe(): print(%s的攻击力是%s%(self.name,self.agg)) pPerson(bob,10,10000,100) bPerson(tony,…

机器学习笔记 - 用于3D物体检测的KITTI数据集的使用及说明

一、什么是 KITTI 数据集&#xff1f; KITTI 是由卡尔斯鲁厄理工学院和芝加哥丰田理工学院开发的自动驾驶数据集&#xff08;目前分2012和2015版本&#xff09;。它是计算机视觉研究中使用的图像和 LIDAR 数据的集合&#xff0c;例如立体视觉、光流、视觉里程计、3D 对象检测和…

14、设计模式之命令模式(Command)

一、什么是命令模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;又叫动作模式或事务模式。它将请求&#xff08;命令&#xff09;封装成对象&#xff0c;使得可以用不同的请求对客户端进行参数化&#xff0c;具体的请求可以在运行时更改…

Css基础——绘制三角形、鼠标样式、轮廓线、放拖拽文本域、vertical-align属性

1、三角形的绘制方法 当一个盒子的width和height都为0时 四个边框都有颜色时&#xff0c;可以显示出三角形来 当其中的三边都是透明&#xff08;transparent&#xff09;的时候&#xff0c;就可以看到一个小三角形 2、鼠标样式&#xff08;cursor&#xff09; 代码部分&#…

sqllab第七关通关笔记

知识点&#xff1a; 利用回显信息不同进行盲注爆破出敏感信息两种绕过方法 单引号闭合绕过&#xff1b;不加注释符 id 1 and 11 完全闭合原始语句的绕过&#xff1b;这题是采用了where id((输入)) id 1)) and 11 -- 首先判断注入类型 构造id1/0 正常回显&#xff0c;字符型注…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Toggle)

组件提供勾选框样式、状态按钮样式及开关样式。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 仅当ToggleType为Button时可包含子组件。 接口 Toggle(options: { type: ToggleType, is…

Shell常用脚本:hadoop集群启动、停止、重启脚本

脚本内容以我搭建的hadoop集群为例&#xff0c;你们自用的时候自行根据你们的情况进行修改即可 hadoop-cluster-manager.sh #!/bin/bash # 1. 调用此脚本前&#xff0c;请使用ssh-keygen -t rsa、ssh-copy-id -f 目标机器这两个命令使得目标机器是免密登录的 # 2. ssh远程执行…

分布式搜索引擎elasticsearch(2)

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;[Domain Specific Language](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html)&#xff09;来定义查…

(done) 使用 vscode 快速把 .ipynb 文件 转为 .py 文件

如图&#xff0c;先点红圈 随后点 Export 后续操作凭直觉 可以使用 vim 的匹配功能把那些难看的符号给删掉&#xff0c;比如 :%s/# \%\%.*$//g

浅谈人工智能

☕️各位观众老爷好&#xff0c;路过点个免费的赞再走呗&#xff01;❤️❤️(*•̀ᴗ•́*)و 前言 随着2024年的到来&#xff0c;人工智能领域正迎来前所未有的变革和发展。随着计算能力的增强、大数据的积累以及机器学习算法的进步&#xff0c; AI的定义和本质 人工智能…

(黑马出品_高级篇_04)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_高级篇_04&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术——可靠性消息服务 今日目标服务异步通信-高级篇1.消息可靠性1.1.生产者消息确认1.1.1.修改配置1.1.2.定义Return回调1.1.3.定义ConfirmCallbac…

【BUG 弹药库】二分模板的优化

文章目录 1. 为什么要优化二分算法&#xff1f;2. 如何去优化原来的二分模板&#xff1f;3. 案例分析 1. 为什么要优化二分算法&#xff1f; ① 平常学习的二分整数的算法模板边界的问题很容易出错&#xff0c;不知道什么时候用 l mid&#xff0c;r mid - 1&#xff1b;或者是…