news 2026/4/16 3:58:03

对于队列的学习

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
对于队列的学习

一.队列的概念

队列(Queue)是一种非常常见的数据结构,它的操作方式与现实生活中的排队场景非常相似。在队列中,元素按照先进先出(FIFO, First In First Out)的顺序被访问,即先进入队列的元素先被移除,后进入的元素后移除

二.队列的结构

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

三.队列的实现

顺序队列

函数接口

voidQueueInit(Queue*pq);voidQueueDestroy(Queue*pq);voidQueuePush(Queue*pq,QDataType x);voidQueuePop(Queue*pq);boolQueueEmpty(Queue*pq);boolQueueFull(Queue*pq);intQueueSize(Queue*pq);QDataTypeQueueFront(Queue*pq);QDataTypeQueueBack(Queue*pq);

队列元素

typedefintQDataType;typedefstructQueue{QDataType data[MAX_SIZE];intfront;intrear;}Queue;

初始化

// 初始化队列voidQueueInit(Queue*pq){assert(pq);pq->front=pq->rear=0;}

销毁

// 销毁队列voidQueueDestroy(Queue*pq){assert(pq);}

判断是否为空

// 判断队列是否为空boolQueueEmpty(Queue*pq){assert(pq);returnpq->front==pq->rear;}

判断是否满了

// 判断队列是否满boolQueueFull(Queue*pq){assert(pq);return(pq->rear+1)%MAX_SIZE==pq->front;}

入队

// 入队操作voidQueuePush(Queue*pq,QDataType x){assert(pq);if(QueueFull(pq)){printf("Queue is full!\n");return;}pq->data[pq->rear]=x;pq->rear=(pq->rear+1)%MAX_SIZE;}

出队

// 出队操作voidQueuePop(Queue*pq){assert(pq);if(QueueEmpty(pq)){printf("Queue is empty!\n");return;}pq->front=(pq->front+1)%MAX_SIZE;}

队列大小

// 获取队列大小intQueueSize(Queue*pq){assert(pq);return(pq->rear-pq->front+MAX_SIZE)%MAX_SIZE;}

队首元素

// 查看队列头部元素QDataTypeQueueFront(Queue*pq){assert(pq);if(QueueEmpty(pq)){printf("Queue is empty!\n");return-1;}returnpq->data[pq->front];}

队尾元素

// 查看队列尾部元素QDataTypeQueueBack(Queue*pq){assert(pq);if(QueueEmpty(pq)){printf("Queue is empty!\n");return-1;}returnpq->data[(pq->rear-1+MAX_SIZE)%MAX_SIZE];}

链式队列

函数接口

voidQueueInit(Queue*pq);voidQueueDestroy(Queue*pq);voidQueuePush(Queue*pq,QDataType);voidQueuePop(Queue*pq);intQueueSize(Queue*pq);boolQueueEmpty(Queue*pq);QDataTypeQueueFront(Queue*pq);QDataTypeQueueBack(Queue*pq);

队列的元素

typedefintQDataType;typedefstructQueueNode{QDataType data;structQueueNode*next;}QNode;typedefstructQueue{QNode*head;QNode*tail;intsize;}Queue;

初始化

voidQueueInit(Queue*pq){assert(pq);pq->head=pq->tail=NULL;pq->size=0;}

销毁

voidQueueDestroy(Queue*pq){assert(pq);QNode*cur=pq->head;while(cur){QNode*next=cur->next;free(cur);cur=next;}pq->head=pq->tail=NULL;pq->size=0;}

插入

voidQueuePush(Queue*pq,QDataType x){QNode*newNode=(QNode*)malloc(sizeof(QNode));if(newNode==NULL){perror("malloc failed");return;}newNode->data=x;newNode->next=NULL;if(pq->head==NULL){assert(pq->tail==NULL);pq->head=pq->tail=newNode;}else{pq->tail->next=newNode;pq->tail=newNode;}pq->size++;}

删除

voidQueuePop(Queue*pq){assert(pq);assert(pq->head!=NULL);// QNode* next = pq->head->next;// free(pq->head);// pq->head = next;// if(pq->head == NULL)// pq->tail = NULL;if(pq->head->next==NULL){free(pq->head);pq->head=pq->tail=NULL;}else{QNode*next=pq->head->next;free(pq->head);pq->head=next;}pq->size--;}

队列的大小

intQueueSize(Queue*pq){assert(pq);returnpq->size;}

判断是否为空

boolQueueEmpty(Queue*pq){assert(pq);returnpq->size==0;}

队首元素

QDataTypeQueueFront(Queue*pq){assert(pq);assert(!QueueEmpty(pq));returnpq->head->data;}

队尾元素

QDataTypeQueueBack(Queue*pq){assert(pq);assert(!QueueEmpty(pq));returnpq->tail->data;}

双端队列

双端队列是一种允许在队列的两端进行插入和删除操作的队列类型。与普通队列(只能在一端入队,另一端出队)不同,双端队列可以在队头队尾两端进行操作

双端队列还有两种受限的情况:

  • 输入受限的双端队列:只许一端插入,两端删除
  • 输出受限的双端队列:只许一端删除,两端插入
    在这里就不做详细解释了,大家有兴趣的可以自己下去实现一下

函数接口

voidDequeInit(Deque*pdq);

队列的元素

typedefintQDataType;typedefstructDequeNode{QDataType data;structDequeNode*prev;// 指向前一个节点structDequeNode*next;// 指向下一个节点}DequeNode;typedefstructDeque{DequeNode*head;DequeNode*tail;intsize;}Deque;

初始化

voidDequeInit(Deque*pdq){assert(pdq);pdq->head=pdq->tail=NULL;pdq->size=0;}

销毁

voidDequeDestroy(Deque*pdq){assert(pdq);DequeNode*cur=pdq->head;while(cur){DequeNode*next=cur->next;free(cur);cur=next;}pdq->head=pdq->tail=NULL;pdq->size=0;}

从队头进出

//从队头进voidDequePushFront(Deque*pdq,QDataType x){assert(pdq);DequeNode*newNode=(DequeNode*)malloc(sizeof(DequeNode));if(newNode==NULL){perror("malloc failed");return;}newNode->data=x;newNode->prev=NULL;newNode->next=pdq->head;if(pdq->head){pdq->head->prev=newNode;}pdq->head=newNode;if(pdq->tail==NULL){pdq->tail=newNode;}pdq->size++;}//从队头出voidDequePopFront(Deque*pdq){assert(pdq);if(pdq->head==NULL){printf("Deque is empty!\n");return;}DequeNode*toDelete=pdq->head;pdq->head=pdq->head->next;if(pdq->head){pdq->head->prev=NULL;}else{pdq->tail=NULL;}free(toDelete);pdq->size--;}

从队尾进出

//从队尾进voidDequePushBack(Deque*pdq,QDataType x){assert(pdq);DequeNode*newNode=(DequeNode*)malloc(sizeof(DequeNode));if(newNode==NULL){perror("malloc failed");return;}newNode->data=x;newNode->prev=pdq->tail;newNode->next=NULL;if(pdq->tail){pdq->tail->next=newNode;}pdq->tail=newNode;if(pdq->head==NULL){pdq->head=newNode;}pdq->size++;}//从队尾出voidDequePopBack(Deque*pdq){assert(pdq);if(pdq->tail==NULL){printf("Deque is empty!\n");return;}DequeNode*toDelete=pdq->tail;pdq->tail=pdq->tail->prev;if(pdq->tail){pdq->tail->next=NULL;}else{pdq->head=NULL;}free(toDelete);pdq->size--;}

队列的大小

intDequeSize(Deque*pdq){assert(pdq);returnpdq->size;}

队头/队尾的元素

QDataTypeDequeFront(Deque*pdq){assert(pdq);assert(pdq->head!=NULL);returnpdq->head->data;}QDataTypeDequeBack(Deque*pdq){assert(pdq);assert(pdq->tail!=NULL);returnpdq->tail->data;}

其他特殊队列

在这里呢,我们只作简单介绍。

  • 阻塞队列:是一种特殊的队列,它的主要特性是能够在队列为空时阻塞消费者线程,或者在队列满时阻塞生产者线程,直到队列状态发生变化。阻塞队列通常用于多线程编程中的生产者-消费者问题,能够有效避免多线程环境中的资源竞争和浪费。

首次了解队列,可能有不足的地方,欢迎大家评论指出问题。
我们一起学习一起进步。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/7 11:12:48

DeepSeek-R1-Distill-Qwen-1.5B优化:量化模型精度保持技巧

DeepSeek-R1-Distill-Qwen-1.5B优化:量化模型精度保持技巧 1. 技术背景与核心价值 随着大模型在推理能力上的持续突破,如何在资源受限的设备上部署高性能语言模型成为边缘计算和终端智能的关键挑战。DeepSeek-R1-Distill-Qwen-1.5B 正是在这一背景下诞…

作者头像 李华
网站建设 2026/4/15 12:56:14

Glyph与传统OCR技术对比:语义理解优势实测

Glyph与传统OCR技术对比:语义理解优势实测 1. 引言:视觉推理时代的语义挑战 随着文档数字化和智能信息提取需求的不断增长,传统OCR(光学字符识别)技术长期作为文本图像处理的核心手段。然而,其在复杂版式…

作者头像 李华
网站建设 2026/4/14 4:02:11

BGE-Reranker-v2-m3 API测试:10块钱搞定全流程验证

BGE-Reranker-v2-m3 API测试:10块钱搞定全流程验证 你是不是也遇到过这样的情况?作为后端工程师,手头有个项目急需测试一个文本重排序模型的API接口,但又不想从零开始搭建环境、写部署代码。自己配置Python环境、安装依赖、处理C…

作者头像 李华
网站建设 2026/4/16 14:31:06

零基础也能玩转AI绘图:Z-Image-Turbo WebUI保姆级入门指南

零基础也能玩转AI绘图:Z-Image-Turbo WebUI保姆级入门指南 阿里通义Z-Image-Turbo WebUI图像快速生成模型 二次开发构建by科哥 阿里通义Z-Image-Turbo WebUI图像快速生成模型 二次开发构建by科哥 1. 学习目标与前置准备 本文是一篇面向零基础用户的 Z-Image-Turb…

作者头像 李华
网站建设 2026/4/12 21:13:58

神经网络调参就像养孩子,这些参数不懂就白忙活

手写识别的烦恼 想象一下这个场景:你正在开发一个能识别手写数字的APP,准备让爷爷奶奶也能用手机记账。结果第一版模型训练出来,你兴冲冲地让奶奶写个"8",模型愣是识别成了"0"。奶奶瞪着眼说:&qu…

作者头像 李华
网站建设 2026/4/16 15:46:11

ComfyUI长视频生成方案:12G显存云端即用,拒绝爆显存

ComfyUI长视频生成方案:12G显存云端即用,拒绝爆显存 你是不是也遇到过这种情况:作为一个想用AI做内容的UP主,手头有创意、有脚本,甚至配音都准备好了,结果一到“视频生成”这一步就卡壳?本地8G…

作者头像 李华