数据结构-队列

目录

  • 前言
  • 一、队列及其抽象数据类型
    • 1.1 队列的基本概念
    • 1.2 队列的抽象数据类型
  • 二、队列的实现
    • 2.1 顺序表示
      • 2.1.1 结构定义
      • 2.1.2 基本操作的实现
    • 2.2 链式表示
      • 2.2.1 结构定义
      • 2.2.2 基本操作的实现
  • 总结

前言

本篇文章介绍队列的基础知识,包括队列的抽象数据类型以及队列的实现。

一、队列及其抽象数据类型

1.1 队列的基本概念

基本定义 限定在表的一端进行插入操作,另一端进行删除操作的线性表
逻辑结构 一种特殊的线性表,一对一关系
存储结构 顺序存储和链式存储,常用顺序存储
运算规则 进行删除操作的一端称为队头,进行插入操作的一端称为队尾,访问结点按照先进先出(FIFO)的原则
队列的插入操作通常称为入队
队列的删除操作通常称为出队

队列的示意图如图1.1所示
在这里插入图片描述

图1.1 队列示意图

1.2 队列的抽象数据类型

ADT Queue
{数据对象:D={ai|ai ∈ElemSet,i=1,2,3,...n,n >= 0}数据关系:S={<ai-1,ai>|ai-1,ai∈D,i=2,...,n}约定an为队尾,a1为队头基本操作:	initQueue(&Q)操作结果:构造一个空的队列QdestroyQueue(&Q)初始条件:队列Q已存在操作结果:队列Q被销毁isEmptyQueue(&Q)初始条件:队列Q已存在操作结果:判断队列Q是否为空队列lengthQueue(&Q)初始条件:队列Q已存在操作结果:返回队列Q的长度enQueue(&Q, e)初始条件:队列Q已存在操作结果:插入元素e为队列的队尾元素deQueue(&Q, &e)初始条件:队列Q已存在操作结果:删除队列Q的队头元素,用e返回被删除的元素getElemQueue(Q, &e)初始条件:队列Q已存在且为非空队列操作结果:用e返回队头元素...
}ADT Queue

二、队列的实现

2.1 顺序表示

2.1.1 结构定义

用顺序存储来表示队列时,要分配一块连续的内存空间来存放队列的元素,并用两个指针变量分别表示队头和队尾。
队列的结构定义如下

//顺序队列的定义#define SUCCESS 1
#define ERROR 0
#define OVERFLOW -1
#define MAXQSIZE 100   //队列最大元素个数//队列数据类型定义
typedef char QElemType;//定义队列类型
struct SeqQueue {QElemType* base;  //队列指针int front;        //数据元素下标,假设为队头指针int rear;		  //数据元素下标,假设为队尾指针
};//定义队列类型指针
typedef struct SeqQueue* PSeqQueue;

利用一块连续的存储单元依次存放自队头到到尾的数据元素
base指针指向这块存储单元的起始地址
front表示队头的下标
rear表示队尾的下标
MAXQSIZE表示队列的最大元素个数
在这里插入图片描述

图2.1 顺序队列示意图

假设MAXQSIZE=4,顺序队列的动态示意图如图2.2
在这里插入图片描述

图2.2 顺序队列的动态示意图

在顺序队列中,同栈一样存在队列溢出问题。
当队列满时,再做入队操作,称为上溢,即对图2.2中的第三个图再做入队操作,会造成上溢;
当队列为空时,再做出队操作,称为下溢,即对图2.2中的第一个和第五个图再做出队操作,会造成下溢

特别地,如果对图2.2中的第五个图进行入队操作,则会造成溢出,而实际上这时队列的前端可能还有可用的空间,因此,这种现象称为假溢出,即front = MAXQSIZE

通常,解决假溢出采用的方法是,把顺序队列从逻辑上看作是一个环形,也称为环形队列,为了在逻辑上形成环形队列,则需要在每次进行入队和出队操作时,对MAXQSIZE进行取余

当环形队列已有MAXQSIZE-1个数据元素时,如果再进行入队操作,则front = rear,与空队列的情况重合,会出现无法判断队列的情况。
为了区分空队列与满队列两种情况的环形队列,一般是牺牲队列的一个结点空间,当队列已有MAXQSIZE-1个数据元素时,则称队列已满的情况。如图2.3所示
空对列:front = rear
满队列: (rear+1)%MAXQSIZE = front

在这里插入图片描述

图2.3 环形队列的情况图

2.1.2 基本操作的实现

  1. 顺序队列的初始化

    //6.1 队列初始化
    void initSeqQueue(PSeqQueue queue)
    {assert(queue);queue->base = (QElemType*)malloc(sizeof(QElemType) * MAXQSIZE);if (NULL == queue->base){printf("malloc fail!\n");exit(OVERFLOW);}queue->front = 0;queue->rear = 0;
    }
    
  2. 顺序队列的销毁

    //6.2 销毁队列
    void destorySeqQueue(PSeqQueue queue)
    {assert(queue);free(queue->base);queue->base = NULL;
    }
    
  3. 顺序队列的入队
    step1 判断队列是否为满队列
    step2 入队

    //6.5 入队
    int enSeqQueue(PSeqQueue queue, QElemType e)
    {assert(queue);if ((queue->rear + 1) % MAXQSIZE == queue->front) //判断队满return ERROR;queue->base[queue->rear] = e;queue->rear = (queue->rear + 1) % MAXQSIZE;return SUCCESS;
    }
    
  4. 顺序入队的出队
    step1 判断队列是否为空队列
    step2 出队

    //6.6 出队
    int deSeqQueue(PSeqQueue queue, QElemType* e)
    {assert(queue);if (queue->front == queue->rear)//判断队空return ERROR;*e = queue->base[queue->front];queue->front = (queue->front + 1) % MAXQSIZE;return SUCCESS;
    }
    
  5. 获取顺序队列的队头元素
    step1 判断队列是否为空队列
    step2 获取队头元素

    //6.7 获取队头元素
    int getQElemSeqQueue(PSeqQueue queue, QElemType* e)
    {assert(queue);if (queue->front == queue->rear)//判断队空return ERROR;*e = queue->base[queue->front];return SUCCESS;
    }
    

2.2 链式表示

2.2.1 结构定义

队列的链接表示就是用一个单链表来表示队列,队列的每个元素对应链表的一个结点,结点的结构与单链表的结构一样。为了强调队头和队尾都是队列的属性,这里对队列增加一层封装,引入LinkQueue结构的定义,这样的存储的队列简称链接队列。

//链接队列的定义
//不带头结点的链表
#define SUCCESS 1
#define ERROR 0
#define OVERFLOW -1//队列数据类型定义
typedef char QElemType;//链接队列结点定义
struct QueueNode;
typedef struct QueueNode* PQueueNode;
struct QueueNode {QElemType data;PQueueNode next;
};//链接队列类型定义
struct LinkQueue {PQueueNode front;	//队头指针PQueueNode rear;		//队尾指针
};
typedef struct LinkQueue LinkQueue;
//指向链接队列类型的指针类型
typedef struct LinkQueue* PLinkQueue;

假设queue是PLinkQueue类型的变量,则图2.4为队列的链接表示
在这里插入图片描述

图2.4 队列的链接表示

2.2.2 基本操作的实现

  1. 链接队列的初始化

    //7.1 队列初始化
    void initLinkQueue(PLinkQueue queue)
    {assert(queue);queue->front = NULL;queue->rear  = NULL;
    }
    
  2. 链接队列的销毁

    //7.2 销毁队列
    void destoryLinkQueue(PLinkQueue queue)
    {assert(queue);PQueueNode p = queue->front;while (p){PQueueNode q = p->next;free(p);p = q;}queue->front = NULL;queue->rear  = NULL;
    }
    
  3. 链接队列的入队

    //7.4 入队
    int enLinkQueue(PLinkQueue queue, QElemType e)
    {assert(queue);//创建一个队列结点PQueueNode newNode = (PQueueNode)malloc(sizeof(struct QueueNode));if (NULL == newNode){printf("malloc fail!n");return ERROR;}newNode->data = e;newNode->next = NULL;if (NULL == queue->front)//判断当前队列是否为空queue->front = newNode;elsequeue->rear->next = newNode;queue->rear = newNode;return SUCCESS;
    }
    
  4. 链接队列的出队

    //7.5 出队
    int deLinkQueue(PLinkQueue queue, QElemType* e)
    {assert(queue);if (NULL == queue->front)//判断空队列return ERROR;*e = queue->front->data;PQueueNode p = queue->front;queue->front = queue->front->next;free(p);if (NULL == queue->front) //如果出队后,队列为空,为了避免野指针,则将队尾置空queue->rear = NULL;return SUCCESS;
    }
    
  5. 获取链接队列的队头元素

    //7.6 获取队头元素
    int getQElemLinkQueue(PLinkQueue queue, QElemType* e)
    {assert(queue);if (NULL == queue->front)  //判断空队列return ERROR;*e = queue->front->data;return SUCCESS;
    }
    

总结

完整代码: https://gitee.com/PYSpring/data-structure/tree/master/queue_code

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

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

相关文章

STM32-串口-UART-Asynchronous

一&#xff0c;发送数据 #include "stdio.h" uint8_t hello[]"Hello,blocking\r\n"; HAL_UART_Transmit(&huart1,hello,sizeof(hello),500); 二&#xff0c;MicroLIB-printf(" hello\r\n") #include "stdio.h" #ifdef __GNUC…

深度学习 DAY2:Transformer(一部分)

前言 Transformer是一种用于自然语言处理&#xff08;NLP&#xff09;和其他序列到序列&#xff08;sequence-to-sequence&#xff09;任务的深度学习模型架构&#xff0c;它在2017年由Vaswani等人首次提出。Transformer架构引入了自注意力机制&#xff08;self-attention mech…

《目标检测数据集下载地址》

一、引言 在计算机视觉的广袤领域中&#xff0c;目标检测宛如一颗璀璨的明星&#xff0c;占据着举足轻重的地位。它宛如赋予计算机一双锐利的 “眼睛”&#xff0c;使其能够精准识别图像或视频中的各类目标&#xff0c;并确定其位置&#xff0c;以边界框的形式清晰呈现。这项技…

题解 CodeForces 1037D Valid BFS? 三种解法 C++

题目传送门 Problem - 1037D - Codeforceshttps://codeforces.com/problemset/problem/1037/Dhttps://codeforces.com/problemset/problem/1037/Dhttps://codeforces.com/problemset/problem/1037/Dhttps://codeforces.com/problemset/problem/1037/Dhttps://codeforces.com/p…

2024微短剧行业生态洞察报告汇总PDF洞察(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p39072 本报告合集洞察从多个维度全面解读微短剧行业。在行业发展层面&#xff0c;市场规模与用户规模双增长&#xff0c;创造大量高收入就业岗位并带动产业链升级。内容创作上&#xff0c;精品化、品牌化趋势凸显&#xff0c;题材走…

HTML<img>标签

例子 如何插入图片&#xff1a; <img src"img_girl.jpg" alt"Girl in a jacket" width"500" height"600"> 下面有更多“自己尝试”的示例。 定义和用法 该<img>标签用于在 HTML 页面中嵌入图像。 从技术上讲&#x…

故障诊断 | BWO白鲸算法优化KELM故障诊断(Matlab)

目录 效果一览文章概述BWO白鲸算法优化KELM故障诊断一、引言1.1、研究背景及意义1.2、故障诊断技术的现状1.3、研究目的与内容二、KELM基本理论2.1、KELM模型简介2.2、核函数的选择2.3、KELM在故障诊断中的应用三、BWO白鲸优化算法3.1、BWO算法基本原理3.2、BWO算法的特点3.3、…

apisix的authz-casbin

目录 1、apisix的auth-casbin官方介绍 2、casbin介绍和使用 2.1基本知识&#xff1a; 2.2使用例子 3、配置插件 4、postman调用 5、auth-casbin的坑 1、apisix的auth-casbin官方介绍 authz-casbin | Apache APISIX -- Cloud-Native API Gateway 2、casbin介绍和使用 c…

基于python+Django+mysql鲜花水果销售商城网站系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

【大模型】ChatGPT 高效处理图片技巧使用详解

目录 一、前言 二、ChatGPT 4 图片处理介绍 2.1 ChatGPT 4 图片处理概述 2.1.1 图像识别与分类 2.1.2 图像搜索 2.1.3 图像生成 2.1.4 多模态理解 2.1.5 细粒度图像识别 2.1.6 生成式图像任务处理 2.1.7 图像与文本互动 2.2 ChatGPT 4 图片处理应用场景 三、文生图操…

【0x0052】HCI_Write_Extended_Inquiry_Response命令详解

目录 一、命令概述 二、命令格式及参数 2.1. HCI_Write_Extended_Inquiry_Response命令格式 2.2. FEC_Required 2.3. Extended_Inquiry_Response 三、生成事件及参数 3.1. HCI_Command_Complete 事件 3.2. Status 四、命令执行流程 4.1. 命令准备阶段(主机端) 4.2…

函数递归的介绍

1.递归的定义 在C语言中&#xff0c;递归就是函数自己调用自己 上面的代码就是 main 函数在函数主体内 自己调用自己 但是&#xff0c;上面的代码存在问题&#xff1a;main 函数反复地 自己调用自己 &#xff0c;不受限制&#xff0c;停不下来。 最终形成死递归&#xff0c;…

小白爬虫——selenium入门超详细教程

目录 一、selenium简介 二、环境安装 2.1、安装Selenium 2.2、浏览器驱动安装 三、基本操作 3.1、对页面进行操作 3.1.1、初始化webdriver 3.1.2、打开网页 3.1.3、页面操作 3.1.4、页面数据提取 3.1.5、关闭页面 ?3.1.6、综合小案例 3.2、对页面元素进行操作 3…

JDK长期支持版本(LTS)

https://blogs.oracle.com/java/post/the-arrival-of-java-23 jdk长期支持版本&#xff08;LTS&#xff09;&#xff1a;JDK 8、11、17、21&#xff1a;

三格电子——MODBUS TCP 转 CANOpen 协议网关

一、产品概述 1.1 产品用途 SG-TCP-COE-210 网关可以实现将 CANOpen 接口设备连接到 MODBUS TCP 网络中。用户不需要了解具体的 CANOpen 和 Modbus TCP 协议即可实现将 CANOpen 设备挂载到 MODBUS TCP 接口的 PLC 上&#xff0c;并和 CANOpen 设备进行 数据交互。 1.2 产品…

在离线无管理员权限的情况下为Linux配置oh-my-zsh(zsh+oh my zsh+powerlevel10k)

0. 前言 最近接触到一台离线环境下的Linux&#xff08;CentOS7&#xff09;&#xff0c;自带的终端实在过于丑陋&#xff08;tcsh&#xff09;&#xff0c;但是搜半天改zsh的教程要么要网、要么要管理员权限&#xff0c;奋而自己折腾半天记录于此以作备忘。 所需环境 一台能…

C 语言雏启:擘画代码乾坤,谛观编程奥宇之初瞰

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一课主要是让大家初步了解C语言&#xff0c;了解我们的开发环境&#xff0c;main函数&#xff0c;库…

Java - WebSocket

一、WebSocket 1.1、WebSocket概念 WebSocket是一种协议&#xff0c;用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接&#xff0c;这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发&#xff0c;并于2…

C语言内存之旅:从静态到动态的跨越

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一 动态内存管理的必要性二 动态…

气膜料仓:工业仓储的高效与安全新选择—轻空间

在工业仓储领域&#xff0c;如何实现高效、安全、环保的存储方式成为企业关注的重点。气膜料仓以其独特的无梁无柱设计和智能化功能&#xff0c;为工业仓储带来了全新的解决方案。 空间利用率高&#xff1a;无障碍的大容量仓储 气膜料仓内部无梁无柱&#xff0c;形成了完全开…