【脚踢数据结构】队列(顺序和链式)

  • (꒪ꇴ꒪ ),Hello我是祐言QAQ
  • 我的博客主页:C/C++语言,Linux基础,ARM开发板,软件配置等领域博主🌍
  • 快上🚘,一起学习,让我们成为一个强大的攻城狮!
  • 送给自己和读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏


        在我们的日常生活中,队列是一个非常常见的现象。无论是在商店结账,还是在公交站等车,我们都在使用队列。在计算机科学中,队列也是一个重要的数据结构,用于处理和组织数据。在这篇文章中,我们将详细探讨队列的定义、操作、以及如何用C语言实现队列。

一、队列的定义


        队列(Queue)是一种特殊类型的线性数据结构,它遵循特定的操作规则,即遵循“先进先出”(FIFO,First-In-First-Out)原则。这意味着在队列中,首先加入的元素将会首先被移除,最后加入的元素将会最后被移除。

         当我们想存入1时,先移动front(队头)然后再写入数据1,拿数据也是一样,但务必保证先移动rear(队尾),再拿出数据,否则将会错位导致出错。

二、顺序队列

      1.  队列结构体定义


        首先需要定义一个顺序队列,我们可以使用结构体来定义一个队列,它包含一个数组(用于存储队列的数据)和三个整数(用于表示队列长度、队首和队尾的位置)。


typedef int Datatype;//队列的结构体定义
typedef struct Quene
{Datatype *q;	//用来存放队列的数据int size;		//队列的长度int front;		//队头int rear;		//队尾
}queue;

    2.  初始化队列


        接下来,我们需要初始化队列。在初始化时,我们将队首和队尾都设置为0,表示队列为空。

//初始化一个队列
queue *init_queue(int size)
{queue *que = malloc(sizeof(queue));if (que!=NULL){que->q = calloc(size, sizeof(Datatype));que->size = size;que->front = 0;que->rear = 0;}return que;
}

    3.  队空和队满


        如果我们想要实现入队和出队操作,我们需要先考虑队列可能会溢出或下溢的情况,因此我们需要判断是否队空或队满。

//队空判断
bool isempty_queue(queue *q)
{return (q->rear == q->front);
}//队满判断
bool isfull_queue(queue *q)
{return ((q->rear+1)%q->size == q->front);
}

    4.  入队和出队

//入队
bool en_queue(queue *que, Datatype data)
{if (isfull_queue(que)){return false;}//先挪rearque->rear = (que->rear+1)%(que->size);//再入数据que->q[que->rear] = data;return true;
}//出队
bool de_queue(queue *que, Datatype *data)
{if (isempty_queue(que)){return false;}//先挪frontque->front = (que->front+1)%(que->size);//再取数据*data = que->q[que->front];return true;
}


        队列是计算机科学中的一个基础概念,它在许多场景中都有应用,如操作系统的任务调度,网络的数据包处理等。理解队列的工作原理并能够实现队列,对于学习和理解计算机科学的其他概念是非常有帮助的。希望这篇文章能帮助你理解和实现队列。

        下面是一个简单的顺序队列举例,实现:输入正整数,添加员工信息,入队,用这个正整数表示员工号;输入负整数,出队(队首),显示该员工的所有信息;否则就退出。

        员工信息:工号、姓名、工资

        完整源码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>#define SIZE 1024
typedef struct people
{int number;		//工号char name[20];	//姓名int money;		//工资
}Datatype;//队列的结构体定义
typedef struct Quene
{Datatype *q;	//用来存放队列的数据int size;		//队列的长度int front;		//队头int rear;		//队尾
}queue;//初始化一个队列
queue *init_queue(int size)
{queue *que = malloc(sizeof(queue));if (que!=NULL){que->q = calloc(size, sizeof(Datatype));que->size = size;que->front = 0;que->rear = 0;}return que;
}//队空判断
bool isempty_queue(queue *q)
{return (q->rear == q->front);
}//队满判断
bool isfull_queue(queue *q)
{return ((q->rear+1)%q->size == q->front);
}//入队
bool en_queue(queue *que, Datatype data)
{if (isfull_queue(que)){return false;}//先挪rearque->rear = (que->rear+1)%(que->size);//再入数据que->q[que->rear] = data;return true;
}//出队
bool de_queue(queue *que, Datatype *data)
{if (isempty_queue(que)){return false;}//先挪frontque->front = (que->front+1)%(que->size);//再取数据*data = que->q[que->front];return true;
}// 添加信息
void init_info(Datatype *data,int n)
{data->number = n;printf("请输入工人信息\n");while(getchar() != '\n');printf("姓名:");scanf("%s", data->name);printf("工资:");scanf("%d", &data->money);
}int main(int argc, char const *argv[]) {queue *q = init_queue(SIZE);int n;Datatype data;while (1) {printf("请输入一个正整数或负数\n");scanf("%d", &n);if (n > 0){init_info(&data, n);en_queue(q, data);continue;}else if(n < 0){Datatype d;if (de_queue(q, &d)) {printf("工号:%d,姓名:%s,工资:%d\n", d.number, d.name, d.money);} else {printf("队列已空,无法出队。\n");}}else{return -1;}}free(q->q);free(q);return 0;
}

三、链式队列

        链式队列(Linked Queue)是一种使用链表来实现的队列数据结构。与顺序队列不同,链式队列的元素并不直接存储在数组中,而是通过链表节点来连接。

        并且 由于使用链表实现,链式队列的大小可以根据需要动态分配和释放内存,避免了固定数组大小可能带来的限制。因此就没有是否队满问题

1.结构体定义

typedef int Datatype;typedef struct Node
{Datatype data;struct Node *next;
}node;typedef struct List_queue
{node *rear;		//队尾指针node *front;	//队头指针int size;		//链式队列的长度(实际的元素的个数)
}L_q;

2.创建新节点和判断队空

//创建新节点
node *create_node(Datatype data)
{node *new = malloc(sizeof(node));if (new != NULL){new->data = data;new->next = NULL;}return new;
}
//链式队列是否为空
bool isempty_list_queue(L_q *q)
{return (q->size == 0);
}

3.初始化队列

//初始化链式队列
L_q *init_list_queue()
{L_q *q = malloc(sizeof(L_q));if (q!=NULL){q->rear = NULL;q->front = NULL;q->size = 0;}return q;
}

3.入队

        入队操作在链表的末尾添加一个新节点,同时更新队尾指针。

//入队
bool en_list_queue(L_q *q, Datatype data)
{//先要将数据创建新节点node *new = create_node(data);if (new==NULL){return false;}//如果是第一次入队,new节点既是队尾,也是队头if (isempty_list_queue(q)){q->rear = new;q->front = new;}else    //不是第一次入队{//先将尾部节点的next指向new节点q->rear->next = new;//尾部节点要变成新节点newq->rear = new;}//队的元素个数要+1q->size++;return true;
}

4.出队

         出队操作移除链表的第一个节点,同时更新队头指针。

//出队
bool de_list_queue(L_q *q, Datatype *data)
{if (isempty_list_queue(q)){return false;}else if(q->size == 1)//只有一个数据的时候{q->rear = NULL;}//在链表不为空的情况下,先拿队头的数据*data = q->front->data;//将队头指向下一个节点q->front = q->front->next;//链式队列的元素个数-1q->size--;return true;
}

 5.遍历

//遍历
void display(L_q *q)
{if (q->front == NULL){return ;}node *p = q->front;while(p->next != NULL){printf("%d ", p->data);p = p->next;}printf("%d\n", p->data);
}

        简单示例:当我们输入正数时,入队并遍历整个队列;当我们输入负数时,出队一个元素,并再次遍历队列;输入0时退出。

int main(int argc, char const *argv[])
{L_q *q = init_list_queue();int num;Datatype data;while(1){scanf("%d", &num);if(num > 0){en_list_queue(q, num);	display(q);	}else if(num < 0){de_list_queue(q, &data);display(q);	}else{break;}}return 0;
}

四、结语

        
        队列作为一种基本的数据结构,在我们的编程生涯中扮演着重要的角色。希望这篇文章提供了一个清晰、详细的队列概述,帮助你理解队列的基本概念和操作,以及如何用C语言实现队列。

        选择顺序队列还是链式队列取决于实际应用的需求。如果你需要一个固定大小的队列,可以考虑使用顺序队列。如果你希望队列大小能够根据需要进行动态调整,那么链式队列更适合。在大多数情况下,链式队列具有更好的扩展性和灵活性。

        更多C语言Linux系统ARM板实战数据结构相关文章,关注专栏:

   手撕C语言

            玩转linux

                    脚踢数据结构

                            6818(ARM)开发板实战

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

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

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

相关文章

通过OpenTelemetry上报Python-flask应用数据(阿里云)

参考文档 https://help.aliyun.com/document_detail/611711.html?spma2c4g.90499.0.0.34a056ddTu2WWq 先按照 方法一&#xff1a;手动埋点上报Python应用数据 步骤测试上报是否正常。 flas 上报 在 手动埋点上报Python应用数据 的基础上&#xff0c;上报flask应用的数据&#…

云计算-知识点大纲

前言&#xff1a;云计算的基本概念学习&#xff0c;基础知识大纲梳理。 目录 云计算的概念 云计算的特征 部署模式 服务模式 云计算的发展 云计算的核心技术 虚拟化技术 常见的虚拟化技术 服务器虚拟化 裸金属型技术 服务器虚拟化技术的特点 存储虚拟化 CPU 内存…

31 | 独角兽企业数据分析

独角兽企业:是投资行业尤其是风险投资业的术语,一般指成立时间不超过10年、估值超过10亿美元的未上市创业公司。 项目目的: 1.通过对独角兽企业进行全面地分析(地域,投资方,年份,行业等),便于做商业上的战略决策 项目数据源介绍 1.数据源:本项目采用的数据源是近…

机器学习鱼书笔记(自用更新)

零、预知识 1.Numpy 使用 介绍&#xff1a;高效的操作多维数组的函数库。 安装&#xff1a;&#xff08;前提已经安装了python&#xff09; pip install numpy导入 import numpy as np创建数组 Numpy最重要的数据结构是多维数组&#xff08;ndarray&#xff09;。通过Numpy&…

【Go语言】Golang保姆级入门教程 Go初学者chapter2

【Go语言】变量 VSCode插件 setting的首选项 一个程序就是一个世界 变量是程序的基本组成单位 变量的使用步骤 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zuxG8imp-1691479164956)(https://cdn.staticaly.com/gh/hudiework/imgmain/image-20…

解决MySQL与Redis缓存一致性的问题

背景 考试系统中&#xff0c;教师会在后台发布一场考试&#xff0c;考试会存储在MySQL和Redis里面&#xff0c;考试有时候是会出错的&#xff0c;我们需要后台修改&#xff0c;如果多个教师在后台并发修改&#xff08;概率不大&#xff09;&#xff0c;可能会出现数据库缓存不…

Linux shell yes命令(不停输出换行的y)(不停输出换行的指定字符串)(脚本自动确认y)

文章目录 yes命令功能doc文档英文中文翻译完整文档 示例应用案例自动为脚本多次确认y yes命令功能 yes命令可以不断地输出换行的指定字符串&#xff0c;不加参数时&#xff0c;不断输出换行的“y”&#xff0c;有时我们需要执行一些需要用户键入“y”确认的脚本&#xff0c;但…

Mysql中如果建立了索引,索引所占的空间随着数据量增长而变大,这样无论写入还是查询,性能都会有所下降,怎么处理?

索引所占空间的增长确实会对MySQL数据库的写入性能和查询性能造成影响&#xff0c;这主要是由于索引数据过多时会导致磁盘I/O操作变得非常频繁&#xff0c;从而使性能下降。为此&#xff0c;可以采取以下几种方式来减缓这种影响&#xff1a; 1. 限制索引的大小&#xff1a;可以…

Oracle-创建PDB

Oracle-创建PDB 创建PDB的方式 从PDB$SEED新建PDB克隆已存在的PDB 本地PDB克隆到同一个CDB中将远程PDB克隆到CDB中将非CDB插入或克隆到CDB中通过插拔的方式创建PDB sql 命令语法 条件 CDB必须open并且read write模式连接CDB$ROOT 用户并且具有CREATEPLUGGABLEDATABASE系统权…

Linux 使用gdb调试C程序

一、gdb的一些基础命令 l&#xff1a;显示代码 l n&#xff1a;跳转到当前代码页的第n行的代码 l filename.c &#xff1a;n&#xff1a;跳转到filename.c文件的第n行代码 b 行号&#xff1a;加断点 info break&#xff1a;查看断点信息 delete 断点编号&#xff1a;删除断点 …

IoTDB原理剖析

一、介绍 IoTDB&#xff08;物联网数据库&#xff09;是一体化收集、存储、管理与分析物联网时序数据的软件系统。 Apache IoTDB采用轻量式架构&#xff0c;具有高性能和丰富的功能。 IoTDB从存储上对时间序列进行排序&#xff0c;索引和chunk块存储&#xff0c;大大的提升时序…

Python爬虫如何更换ip防封

作为一名长期扎根在爬虫行业动态ip解决方案的技术员&#xff0c;我发现很多人常常在使用Python爬虫时遇到一个困扰&#xff0c;那就是如何更换IP地址。别担心&#xff0c;今天我就来教你如何在Python爬虫中更换IP&#xff0c;让你的爬虫不再受到IP封锁的困扰。废话不多说&#…

linux安装wkhtmltopdf(清晰明了)

概述 在公司项目中使用到 wkhtmltopdf 转换PDF&#xff0c;由于 wkhtmltox-0.12.5 版本 echarts 图形虚线样式&#xff0c;需要升级 wkhtmltox-0.12.6 版本来解决。 官网地址 wkhtmltopdf &#xff1a;https://wkhtmltopdf.org/ windows 安装 下载流程及安装流程 进入官…

gazebo 导入从blender导出的dae等文件

背景&#xff1a; gazebo 模型库里的模型在我需要完成的任务中不够用&#xff0c;还是得从 solidworks、3DMax, blender这种建模软件里面在手动画一些&#xff0c;或者去他们的库里面在挖一挖。 目录 1 blender 1-1 blender 相关links 1-2 install 2 gazebo导入模型 2-1 g…

开封Geotrust单域名https证书推荐

Geotrust作为全球领先的数字证书颁发机构之一&#xff0c;拥有多年的数字证书颁发经验&#xff0c;其数字证书被广泛应用于电子商务、在线支付、企业通讯、云计算等领域&#xff0c;为用户提供了安全可靠的保障。而Geotrust旗下的单域名https证书是大多数客户创建网站时的选择之…

技术应用:Docker安全性的最佳实验|聊聊工程化Docker

&#x1f525; 技术相关&#xff1a;《技术应用》 ⛺️ I Love you, like a fire! 文章目录 首先&#xff0c;使用Docker Hub控制访问其次&#xff0c;保护密钥写在最后 不可否认&#xff0c;能生存在互联网上的软件都是相互关联的&#xff0c;当我们开发一款应用程序时&#x…

如何设计一个高性能/高并发/高可用/高可靠/可扩展的系统?

作者&#xff1a;阿秀 校招八股文学习网站&#xff1a;https://interviewguide.cn 这是阿秀的第「293」篇原创 小伙伴们大家好&#xff0c;我是阿秀。 面试者和求职者的关系就好像是矛与盾&#xff0c;一个拼命堆自己的防装&#xff0c;反伤刺甲、魔女斗篷都往身上穿&#xff1…

java获取到heapdump文件后,如何快速分析?

简介 在之前的OOM问题复盘之后&#xff0c;本周&#xff0c;又一Java服务出现了内存问题&#xff0c;这次问题不严重&#xff0c;只会触发堆内存占用高报警&#xff0c;没有触发OOM&#xff0c;但好在之前的复盘中总结了dump脚本&#xff0c;会在堆占用高时自动执行jstack与jm…

MD-MTSP:星雀优化算法NOA求解多仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)

一、星雀优化算法NOA 星雀优化算法(Nutcracker optimizer algorithm,NOA)由Mohamed Abdel-Basset等人于2023年提出&#xff0c;该算法模拟星雀的两种行为&#xff0c;即&#xff1a;在夏秋季节收集并储存食物&#xff0c;在春冬季节搜索食物的存储位置。星雀优化算法(Nutcrack…

WPS Office 代码执行漏洞(QVD-2023-17241)

目录 本地利用弹计算器&#xff08;自娱自乐&#xff09; 原理分析 msf的利用 1.修改win11中的hosts文件 2.MSF生成一个C#后门 3.shellcode替换 4.在创建html的目录&#xff0c;用python打开http服务来捕获请求 5.开启监听 6.在win11中点击poc文档&#xff0c;可以看到k…