数据结构:队列(链表和数组模拟实现)

目录

1.何为队列

2.链表模拟实现

2.1 节点和队列创建

2.2 初始化队列

2.3 入队操作

2.4 出队操作

2.5 遍历队列

2.6 获取队首和队尾元素

2.7 判断队列是否为空

2.8 完整实现

3. 数组模拟实现

3.1 创建队列

3.2 入队和出队操作

3.3 遍历队列

3.4 获取队首和队尾元素

 3.5 判断队列是否为空

3.6 完整实现


1.何为队列

       队列也是一种数据结构,队列和栈不同的是,栈是先进后出,而队列是先进先出,这跟我们平时排队是一样的,先排的先办完事走,后排的后走,队列又被称为先进先出的线性表,简称FIFO(First In First Out)

       那队列是怎么来实现的呢?下面从链表和数组两个方面来模拟实现

2.链表模拟实现

2.1 节点和队列创建

       我们用链表来模拟每个队列元素,可以用链表节点来表示,data是数据域,next是指针域

typedef struct QueueNode
{int data;struct QueueNode* next;
}QueueNode;

      栈有栈顶,那队列也应该有队首和队尾

typedef struct Queue
{QueueNode* head, * tail;int size;
}Queue;

2.2 初始化队列

      创建一个队列和队首、队尾,并进行初始化

void QueueCreate(Queue* que)
{que->head = NULL;que->tail = NULL;que->size = 0;
}

2.3 入队操作

      万事具备,就差元素入队填满队列了!

      队列的插入操作叫做入队,它是将数据元素从队尾进行插入的过程

      4号元素是原先的队尾,在它后面插入元素6,就是入队的过程

      我们首先创建一个值为data的队列节点vtx,如果队尾非空,则将vtx作为队尾元素的后继,否则将队首元素置为vtx,队尾元素变成vtx,队列的长度加一。

void QueueEnter(Queue* que, int data)//入队就是将元素从队尾插入的过程
{QueueNode* vtx = (QueueNode*)malloc(sizeof(QueueNode));vtx->data = data;vtx->next = NULL;if (que->tail){que->tail->next = vtx;}else{que->head = vtx;}que->tail = vtx;que->size++;
}

2.4 出队操作

      队列的删除操作叫做出队,它是将队首元素进行删除的过程。

      将队首变成原先队首的后继元素,就实现了出队操作

      我们将队首元素缓存到temp中,将当前的队首变成temp的后继,释放temp的内存,队列长度减一,如果此时队列为空,则将队尾置为空。

void QueueDelete(Queue* que)
{QueueNode* temp = que->head;que->head = temp->next;free(temp);que->size--;if (que->size == 0){que->tail = NULL;}

2.5 遍历队列

    我们建立一个cur指向队首,如果cur!=NULL,则cur变为cur的后继

void QueueTravel(Queue* que)
{QueueNode* cur = que->head;while (cur){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}

2.6 获取队首和队尾元素

int QueueGetFront(Queue* que)//获取队首元素
{return que->head->data;
}
int QueueGetBack(Queue* que)//获取队尾元素
{return que->tail->data;
}

2.7 判断队列是否为空

     如果队首等于队尾,说明队列为空,否则队列不为空。

bool QueueIsEmpty(Queue* que)
{return que ->head == que->tail;
}

2.8 完整实现

#include<stdio.h>
#include<stdlib.h>
typedef struct QueueNode//创建队列节点
{int data;struct QueueNode* next;
}QueueNode;
typedef struct Queue//创建队列结构
{QueueNode* head, * tail;//队首允许删除,队尾允许插入int size;
}Queue;
void QueueCreate(Queue* que)//队列初始化
{que->head = NULL;que->tail = NULL;que->size = 0;
}
void QueueEnter(Queue* que, int data)//入队就是将元素从队尾插入的过程
{QueueNode* vtx = (QueueNode*)malloc(sizeof(QueueNode));vtx->data = data;vtx->next = NULL;if (que->tail){que->tail->next = vtx;}else{que->head = vtx;}que->tail = vtx;que->size++;
}
void QueueDelete(Queue* que)//出队就是将元素从队尾删除的过程
{QueueNode* temp = que->head;que->head = temp->next;free(temp);que->size--;if (que->size == 0){que->tail = NULL;}
}
void QueueTravel(Queue* que)//队列的遍历
{QueueNode* cur = que->head;while (cur){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}
int QueueGetFront(Queue* que)//获取队首元素
{return que->head->data;
}
int QueueGetBack(Queue* que)//获取队尾元素
{return que->tail->data;
}
bool QueueIsEmpty(Queue* que)//判断队列是否为空
{return que ->head == que->tail;
}
int main()
{Queue* que = (Queue*)malloc(sizeof(Queue));QueueCreate(que);int n;scanf_s("%d\n", &n);//执行n次入队操作while (n--){int data;scanf_s("%d", &data);QueueEnter(que, data);}//遍历并打印队列元素QueueTravel(que);//打印队首元素printf("队首元素为:%d\n", QueueGetFront(que));//打印队尾元素printf("队尾元素为:%d\n", QueueGetBack(que));//判断队列是否为空printf("%d",QueueIsEmpty(que));return 0;}

3. 数组模拟实现

3.1 创建队列

     在用数组创建队列时,不需要我们开辟空间,数组已经开好了

const int N = 100010;
int q[N];//队列
int hh = 0;//hh表示队首
int tt = -1;//tt表示队尾

3.2 入队和出队操作

     我们只需要hh++即可完成队首元素的删除操作,并不是真的删除,而是把队首元素的下标从队列数组中剔除了。

q[++tt] = x;//入队
hh++;//出队

3.3 遍历队列

//遍历并打印队列每个元素的值
for (int i = 0; i <=tt;i++)
{printf("%d ", q[i]);
}
printf("\n");

3.4 获取队首和队尾元素

//获取队首的值
printf("队首的值为:%d\n", q[hh]);//获取队尾的值
printf("队尾的值为:%d\n", q[tt]);

3.5 判断队列是否为空

     如果hh<=tt说明队列不为空

//判断队列是否为空,如果hh<=tt,则表示不为空
if (hh <= tt)printf("队列不为空");

3.6 完整实现

#include<stdio.h>
const int N = 100010;
int q[N];
int hh = 0;//hh表示队首
int tt = -1;//tt表示队尾
int main()
{int n;scanf_s("%d", &n);while (n--){int x;scanf_s("%d", &x);q[++tt] = x;//入队操作,向队尾插入一个数}//遍历并打印队列每个元素的值for (int i = 0; i <=tt;i++){printf("%d ", q[i]);}printf("\n");hh++;//出队操作,从队首删除一个数printf("队首的值为:%d\n", q[hh]);//判断队列是否为空,如果hh<=tt,则表示不为空if (hh <= tt)printf("队列不为空");return 0;
}

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

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

相关文章

数据转换的三剑客:Pandas 中 apply、map 和 applymap 方法的应用指南

数据转换的三剑客&#xff1a;Pandas 中 apply、map 和 applymap 方法的应用指南 ​ 在 Pandas 中&#xff0c;apply、map 和 applymap 是常用的数据转换和处理方法&#xff0c;它们为数据分析和数据处理提供了灵活的功能。这些方法可以根据具体的需求选择合适的方法进行操作。…

2023结婚成家,2024借势起飞

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

今晚咱们一起来场特别的技术跨年!!

▼最近直播超级多&#xff0c;预约保你有收获 今晚跨年直播&#xff1a;《LLM在电商推荐系统的应用案例实战》 —1— 今晚咱们来场技术跨年&#xff01; LLM 大模型无疑是2023年最重磅的技术&#xff0c;逐渐在各行各业产生了越来越重要的实质影响&#xff0c;2024年的钟声今晚…

uni-app引入vant表单(附源码)

新建项目 下载安装vant npm i vant main.js引入 import { Form } from vant; import { Field } from vant;Vue.use(Form); Vue.use(Field);代码引入 <van-form submit"onSubmit"><van-fieldclass"rePwd"v-model"username"name"请…

我的512天创作者纪念日总结:高效、高现

文章目录 512天创作者纪念日&#xff1a;2023年的12月31日CSDN的512天消息提醒第一篇文章&#xff0c;最后一篇文章总计847篇文章&#xff0c;每月发文分布512天&#xff0c;各专栏文章统计512天&#xff0c;互动总成绩 512天创作者纪念日&#xff1a;2023年的12月31日 2023年…

LabVIEW开发滚动轴承故障诊断系统

LabVIEW开发滚动轴承故障诊断系统 在工业自动化和机械维护领域&#xff0c;滚动轴承的故障诊断是至关重要的。开发了一个基于LabVIEW的振动信号分析系统。这一系统集成了先进的信号处理技术&#xff0c;如经验模式分解&#xff08;EMD&#xff09;、Morlet小波滤波器和隐Marko…

【LMM 004】LLaVA-RLHF:用事实增强的 RLHF 对齐大型多模态模型

论文标题&#xff1a;Aligning Large Multimodal Models with Factually Augmented RLHF 论文作者&#xff1a;Zhiqing Sun, Sheng Shen, Shengcao Cao, Haotian Liu, Chunyuan Li, Yikang Shen, Chuang Gan, Liang-Yan Gui, Yu-Xiong Wang, Yiming Yang, Kurt Keutzer, Trevor…

【Redis技术专区】「原理分析」探讨Redis6.0为何需要启用多线程

探讨Redis 6.0为何需要启用多线程 背景介绍开启多线程多线程的CPU核心配置IO多线程模式单线程处理方式多线程处理方式 为什么要开启多线程&#xff1f;充分利用多核CPU提高网络I/O效率响应现代应用需求 多线程实现启用多线程 最后总结 背景介绍 在Redis 6.0版本中&#xff0c;…

计算机网络(6):应用层

每个应用层协议都是为了解决某一类应用问题&#xff0c;而问题的解决又往往是通过位于不同主机中的多个应用进程之间的通信和协同工作来完成的。 应用层的具体内容就是规定应用进程在通信时所遵循的协议。 应用层的许多协议都是基于客户服务器方式。即使是对等通信方式&#x…

【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数

文章目录 &#x1f680;前言&#x1f680;C有何过C之处&#xff1f;&#x1f680;C中的关键字&#x1f680;命名空间✈️为什么要引入命名空间&#xff1f;✈️命名空间的定义✈️如何使用命名空间中的内容呢&#xff1f; &#x1f680;C中的输入和输出✈️C标准库的命名空间✈…

实战入门 K8s剩下三个模块

1.Label Label是kubernetes系统中的一个重要概念。它的作用就是在资源上添加标识&#xff0c;用来对它们进行区分和选择。 Label的特点&#xff1a; 一个Label会以key/value键值对的形式附加到各种对象上&#xff0c;如Node、Pod、Service等等 一个资源对象可以定义任意数量…

圆梦、取舍、成长—独孤风的2023年回顾

大家好&#xff0c;我是独孤风&#xff0c;一位曾经的港口煤炭工人&#xff0c;目前在某国企任大数据负责人&#xff0c;公众号大数据流动的作者。 2023年马上就要过去了&#xff0c;这一年我们结束了三年核酸检测的生活。一切回归到正常的轨迹。回望这一年可能更多的时候会觉得…

计算机操作系统(OS)——P5设备管理

1、I/O设备的概念和分类 什么是I/O设备 I/O就是输入/输出&#xff08;Input/Output&#xff09;。 I/O设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出数据的外部设备&#xff0c;属于计算机中的硬件部件。 UNIX系统将外部设备抽象为一种特殊的文件&#x…

30 UVM Adder Testbench Example

1 Adder Design 加法器设计在时钟的上升沿产生两个变量的加法。复位信号用于clear out信号。注&#xff1a;加法器可以很容易地用组合逻辑开发。引入时钟和重置&#xff0c;使其具有测试台代码中时钟和重置的样子/风格。 module adder(input clk, reset, input [7:0] in1, in…

数据结构模拟实现LinkedList双向不循环链表

目录 一、双向不循环链表的概念 二、链表的接口 三、链表的方法实现 &#xff08;1&#xff09;display方法 &#xff08;2&#xff09;size方法 &#xff08;3&#xff09;contains方法 &#xff08;4&#xff09;addFirst方法 &#xff08;5&#xff09;addLast方法 …

QT音频编程实战项目(一)ui搭建和槽函数的完成

第一个类实现播放音乐&#xff0c;第二个类实现歌曲列表&#xff0c;第三个类是播放本地歌曲 上边是歌曲的总时长&#xff0c;下边是当前播放的时长。 所需要的槽函数如上图。 这个是构造函数&#xff1a; …

Group k-fold解释和代码实现

Group k-fold解释和代码实现 文章目录 一、Group k-fold解释和代码实现是什么&#xff1f;二、 实验数据设置2.1 实验数据生成代码2.2 代码结果 三、实验代码3.1 实验代码3.2 实验结果3.3 结果解释 四、总结 一、Group k-fold解释和代码实现是什么&#xff1f; 0&#xff0c;1…

找不到msvcp140.dll文件的多种解决方法,五个方法轻松搞定

msvcp140.dll是Microsoft Visual C 2015 Redistributable的一个组件&#xff0c;它是运行许多Windows应用程序所必需的动态链接库文件之一。当这个文件丢失或损坏时&#xff0c;就会导致相关应用程序无法正常启动或运行。本文将全面解析msvcp140.dll丢失的原因以及解决方法。 关…

JavaWeb——前端之AjaxVue

6. 前后端交互 6.1 Ajax&#xff08;原生的&#xff09; 概念&#xff1a; Asynchronous JavaScript And XML&#xff08;异步的JavaScript和XML&#xff09; 作用&#xff1a; 数据交互&#xff1a;通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据异步交…

爱思唯尔的KBS——模板、投稿、返修、接收的总结

第二篇论文终于是接受了QAQ&#xff0c;被审稿人疯狂拖时间&#xff0c;KBS是真难绷啊 由于之前发布过关于爱思唯尔旗下的ESWA博客&#xff0c;KBS和ESWA是类似的&#xff0c;因此本篇博客主要说下区别以及期间碰到的各种情况&#xff0c;有疑问依然可以在评论区说&#xff0c;…