当前位置: 首页 > news >正文

【数据结构】队列的实现

白日去如箭,达者惜今阳。                                                   --朱敦儒

目录 

🚁前言:​

🏝️一.队列的概念及结构 

🌻二.队列各种功能的实现

🍍1.队列的初始化

🏝️2.队列的尾入

🍉3.队列头的元素

🍁4.队列的头出

🍀5.判断是否为空

🚲6.队列尾的元素

🪂7.销毁队列

🌴三.队列的全部代码 

🌻1.Queue.h:

🍌2.Queue.c:

🍈3.test.c:


🚁前言:

前几天我们对栈进行了实现,栈是数据先进后出,而今天我们要是实现的队列是完全相反的,队列
是数据先进先出。而在栈中我们使用的顺序表(数组)来实现的。而队列却用单链表来实现是更加合适的。

在队列入数据的时候,相当于是尾插,而队列出数据的时候相当于是头删。

  • 队列的顺序结构
    入队,不需要移动任何元素,时间复杂度为O(1)。
    出队,所有元素需要往前移动,时间复杂度为O(N)。
  • 队列的链式结构
    首先我们定义两个指针,队头指针指向第一个节点,队尾指针指向尾节点。
    入队(尾插),时间复杂度为O(1)。
    出队(头删),时间复杂度为O(1)。
    结论:所以我们使用单链表来实现队列。

🏝️一.队列的概念及结构 

     队列:只允许在一端进行插入数据操作,在另一端进行数据操作的特殊线性表,队列具有先进先出FIFO(Frist in First out)。

入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为对头。

队列的初始结构:单链表实现

typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;//单链表QDataType data;
}QNode;typedef struct Queue
{QNode* head;//队列头QNode* tail;//队列尾
}Queue;

🌻二.队列各种功能的实现

🍍1.队列的初始化

  这里我们实现的单链表是无头不循环的单链表。所以我们把队列头和队列尾初始化为空指针。

//初始化
void QueueInit(Queue* ps)
{assert(ps);ps->head = ps->tail = NULL;
}

🏝️2.队列的尾入

    对于队列的尾入,我们要分为两种情况:
第一种:第一次尾入数据的时候,队列头和队列尾都是指向的同一个位置,并且都是空,当我们要尾入的时候创建一个新的结点,把新结点赋值给队列的头和队列的尾。

第二种:队列已经有数据了,我们把新的结点链接到尾后面,然后再把新结点赋值为新的结点,也就是更新队列的尾。总结:队列头是一直不变的,队列尾入一个数据就需要把队列尾往后面移动一位。
 

//队尾入
void QueuePush(Queue* ps,QDataType x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));//创建一个新的结点if (newnode == NULL){perror("malloc\n");return;}newnode->data = x;newnode->next = NULL;if ( ps->tail == NULL)//第一种情况{ps->head=ps->tail = newnode;//新结点就是队列尾和队列头}else//第二种情况{ps->tail->next = newnode;//队列尾链接新的结点ps->tail = newnode;//更新队列尾}
}

🍉3.队列头的元素

     需要知道队列头的元素是非常简单的,只需要返回队列头的元素即可。

//头的元素
QDataType QueueFront(Queue* ps)
{assert(ps);assert(ps->head);return ps->head->data;
}

🍁4.队列的头出

   队列的头出也是分为两种情况:
第一种:当队列只有一个结点的时候,直接free掉第一个结点即可,然后把队列头和对列尾赋值尾空即可。
第二种:当队列有两个及两个以上的结点的时候,我们先保存队列头的下一个结点,然后free掉队列头即可。

//对头出
void QueuePop(Queue* ps)
{assert(ps);assert(ps->head);if (ps->head->next == NULL)//当队列只有一个结点时{free(ps->head);ps->head = ps->tail = NULL;}else//当队列有两个或者两个以上的结点时{QNode* next = ps->head->next;//free掉第一个结点时,先保存下一个结点free(ps->head);ps->head = next;}
}

🍀5.判断是否为空

在队列出的时候,我们出一个数据就要判断一下队列是否为空,如果为空,我们就不能出数据了。
我们还是和栈的判断空一样,使用bool值来判断。

//判断是否为空
bool QueueEmpty(Queue* ps) 
{assert(ps);return ps->head == NULL;
}

有了上面的代码我们就可以把出队列的数据给打印一下。

很明显这和队列的结构时一致的,即先进先出。 

🚲6.队列尾的元素

//尾的元素
QDataType QueueBack(Queue* ps)
{assert(ps);assert(ps->head);return ps->tail->data;
}

🪂7.销毁队列

最后退出程序,我们再把队列给销毁一下。

//销毁队列
void QueueDestroy(Queue* ps)
{assert(ps);QNode* cur = ps->head;while (cur){QNode* next = ps->head->next;free(ps->head);ps->head = next;cur = next;}ps->head = ps->tail == NULL;
}

最后我们再把队列的功能给实现一下:

 

🌴三.队列的全部代码 

🌻1.Queue.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* head;QNode* tail;
}Queue;//初始化
void QueueInit(Queue* ps);//队尾插
void QueuePush(Queue* ps,QDataType x);//队头出
void QueuePop(Queue* ps);//头的元素
QDataType QueueFront(Queue* ps);//尾的元素
QDataType QueueBack(Queue* ps);//队列的元素个数
int QueueSize(Queue* ps);//判断是否为空
bool QueueEmpty(Queue* ps);//销毁队列
void QueueDestroy(Queue* ps);

🍌2.Queue.c:
 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"//初始化
void QueueInit(Queue* ps)
{assert(ps);ps->head = ps->tail = NULL;
}//队尾入
void QueuePush(Queue* ps,QDataType x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc\n");return;}newnode->data = x;newnode->next = NULL;if ( ps->tail == NULL){ps->head=ps->tail = newnode;}else{ps->tail->next = newnode;ps->tail = newnode;}
}//对头出
void QueuePop(Queue* ps)
{assert(ps);assert(ps->head);if (ps->head->next == NULL)//当队列只有一个结点时{free(ps->head);ps->head = ps->tail = NULL;}else//当队列有两个或者两个以上的结点时{QNode* next = ps->head->next;//free掉第一个结点时,先保存下一个结点free(ps->head);ps->head = next;}
}//头的元素
QDataType QueueFront(Queue* ps)
{assert(ps);assert(ps->head);return ps->head->data;
}//尾的元素
QDataType QueueBack(Queue* ps)
{assert(ps);assert(ps->head);return ps->tail->data;
}//队列的元素个数
int QueueSize(Queue* ps)
{int count = 0;QNode* cur = ps->head;while (cur){count++;cur = cur->next;}return count;
}//销毁队列
void QueueDestroy(Queue* ps)
{assert(ps);QNode* cur = ps->head;while (cur){QNode* next = ps->head->next;free(ps->head);ps->head = next;cur = next;}ps->head = ps->tail == NULL;
}//判断是否为空
bool QueueEmpty(Queue* ps) 
{assert(ps);return ps->head == NULL;
}

🍈3.test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
int main()
{QNode q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);printf("对于队列 1 2 3 4 出的数据为:\n");while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueuePush(&q, 5);QueuePush(&q, 6);QueuePush(&q, 7);QueuePush(&q, 8);printf("\n");printf("队列的元素为 5 6 7 8\n");printf("队列头的元素为:\n");int first = QueueFront(&q);printf("%d\n", first);printf("队列尾的元素为:\n");int tail = QueueBack(&q);printf("%d\n", tail);printf("队列的元素的个数为:\n");int count = QueueSize(&q);printf("%d\n", count);QueueDestroy(&q);printf("退出程序\n");printf("队列已经被销毁……\n");return 0;
}

相关文章:

【数据结构】队列的实现

白日去如箭&#xff0c;达者惜今阳。 --朱敦儒目录 &#x1f681;前言&#xff1a;​ &#x1f3dd;️一.队列的概念及结构 &#x1f33b;二.队列各种功能的实现 &#x1f34d;1.队列的初始化 &#x1f3dd;️2.队列…...

【数据库】— 无损连接、Chase算法、保持函数依赖

【数据库】— 无损连接、Chase算法 Chase算法Chase算法举例一种简便方法&#xff1a;分解为两个模式时无损连接和函数依赖的一个简单例子 Chase算法 形式化定义&#xff1a; 构造一个 k k k行 n n n列的表格&#xff0c;每行对应一个模式 R i ( 1 ≤ i ≤ k ) Ri (1≤i ≤ k)…...

用英语翻译中文-汉字英文翻译

中文转英语翻译 作为一款高效、准确的中文转英语翻译软件&#xff0c;我们的产品可以帮助全球用户更好地沟通和合作&#xff0c;实现跨文化交流。 在全球化的今天&#xff0c;中英文翻译已经成为商务、学术、娱乐等各个领域不可或缺的一部分。我们的中文转英语翻译软件是为了…...

瑞吉外卖项目——缓存优化

用户数量多&#xff0c;系统访问量大 频繁访问数据库&#xff0c;系统性能下降&#xff0c;用户体验差 环境搭建 maven坐标 在项目的pom.xml文件中导入spring data redis的maven坐标: <dependency><groupId>org.springframework.boot</groupId><arti…...

从头创建一个新的浏览器,这合理吗?

从头构建一个新浏览器&#xff1f;这如果是不是个天大的“伪需求”&#xff0c;便是一场开发者的噩梦&#xff01; 要知道&#xff0c;如果没有上百亿的资金和数百名研发工程师的投入&#xff0c;从头开始构建一个新的浏览器引擎&#xff0c;几乎是不可能的。然而SerenityOS系统…...

TypeScript泛型类型和接口

本节课我们来开始了解 TypeScript 中泛型类型的概念和接口使用。 一&#xff0e;泛型类型 1. 前面&#xff0c;我们通过泛型变量的形式来存储调用方的类型从而进行检查&#xff1b; 2. 而泛型也可以作为类型的方式存在&#xff0c;理解这一点&#xff0c;先了解下函数的…...

docker命令

1.运行 docker-compose up 2.查看命令 docker images 3.删掉docker镜像: docker rmi -f [id] docker卸载 1.杀死docker有关的容器&#xff1a; docker kill $(docker ps -a -q) 2.删除所有docker容器&#xff1a;docker rm $(docker ps -a -q) 3.删除所有docker镜像&…...

2023 年 3 月 NFT 月度报告

作者&#xff1a;Danielfootprint.network 数据来源&#xff1a;NFT Monthly Report 三月份的 NFT 市场上出现了两个有趣的趋势。一方面&#xff0c;Polygon 链尽管在二月份有所突破&#xff0c;达到了 NFT 总交易量的 4.2%&#xff0c;但于三月再次跌至 1% 以下&#xff0c;…...

【http】 get方法和Post方法区别;http和https

get方法和Post方法 get方法&#xff1a;通过url传参&#xff0c;回显输入的私密信息&#xff0c;不够私密 Post方法&#xff1a;通过正文传参&#xff0c;不会回显&#xff0c;一般私密性有保证。 一般如果上传的图片&#xff0c;音频比较大&#xff0c;推荐Post方法&#x…...

第三章 法的渊源与法的分类

目录 第一节 法的渊源的分类 一、法的渊源释义二、法的渊源种类 第二节 正式法源 一、正式法源的含义二、当代中国的正式法源三、正式法源的一般效力原则 第三节 非正式法源 一、当代中国的非正式法源 第四节 法的分类 一、法的一般分类二、法的特殊分类 第一节 法的渊源的…...

在Ubuntu18.04或者20.04下搭建edk2运行环境

#更新完之后依次执行下面两条命令 1.apt-get update 2.apt-get upgrade 如果执行之后出现源不能更新的问题,到/etc/apt/sources.list.d 下删除对应的ppa源重新更新即可解决 git clone https://github.com/tianocore/edk2.git cd edk2 git submodule update --init 如果git cl…...

多线程编程常用函数用法

一、多线程编程常用函数用法 1、pthread_create 头文件 #include<pthread.h>函数声明 int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*&#xff08;*start_rtn)(void*),void *restrict arg)函数功能 pthread_create是UNIX环境…...

C++ 标准模板库(Standard Template Library,STL)

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…...

一个寄存器的bit2 bit3位由10修改成11,C示例

方法1&#xff1a; 如果需要将一个寄存器中的 bit2 和 bit3 两个位从 11 修改为 10&#xff0c;可以使用如下的 C 语言代码实现&#xff1a; // 将寄存器的 bit2 和 bit3 位从 11 修改为 10 volatile uint32_t *reg_addr (volatile uint32_t *)0x12345678; // 假设寄存器地址…...

【洛谷】P1631 序列合并

【洛谷】 P1631 序列合并 题目描述 有两个长度为 N N N 的单调不降序列 A , B A,B A,B&#xff0c;在 A , B A,B A,B 中各取一个数相加可以得到 N 2 N^2 N2 个和&#xff0c;求这 N 2 N^2 N2 个和中最小的 N N N 个。 输入格式 第一行一个正整数 N N N&#xff1b; 第二…...

2023年七大最佳勒索软件解密工具

勒索软件是目前最恶毒且增长最快的网络威胁之一。作为一种危险的恶意软件&#xff0c;它会对文件进行加密&#xff0c;并用其进行勒索来换取报酬。 幸运的是&#xff0c;我们可以使用大量的勒索软件解密工具来解锁文件&#xff0c;而无需支付赎金。如果您的网络不幸感染了勒索软…...

prettier 命令行工具来格式化多个文件

prettier 命令行工具来格式化多个文件 你可以使用 prettier 命令行工具来格式化多个文件。以下是一个使用命令行批量格式化文件的示例&#xff1a; 安装 prettier 如果你还没有安装 prettier&#xff0c;你可以使用以下命令安装它&#xff1a; npm install -g prettier 进入…...

我发现了PMP通关密码!这14页纸直接背!

一周就能背完的PMP考试技巧只有14页纸 共分成了4大模块 完全不用担心看不懂 01关键词篇 第1章引论 1.看到“驱动变革”--选项中找“将来状态” 2.看到“依赖关系”--选项中找“项目集管理” 3.看到“价值最大化”--选项中找“项目组合管理” 4.看到“可行性研究”--选项中…...

Medical X-rays Dataset汇总(长期更新)

目录​​​​​​​ ChestX-ray8 ChestX-ray14 VinDr-CXR VinDr-PCXR ChestX-ray8 ChestX-ray8 is a medical imaging dataset which comprises 108,948 frontal-view X-ray images of 32,717 (collected from the year of 1992 to 2015) unique patients with the text-mi…...

一文告诉你如何做好一份亚马逊商业计划书的框架

“做亚马逊很赚钱”、“我也来做”、“哎&#xff0c;亏钱了”诸如此类的话听了实在是太多。亚马逊作为跨境电商老大哥&#xff0c;许多卖家还是对它怀抱着很高的期许。但是&#xff0c;事实的残酷的。有人入行赚得盆满钵盈&#xff0c;自然也有人亏得血本无归。 会造成这种两…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...