数据结构—队列

目录

一、队列的定义

二、队列的顺序储存结构

2.1顺序队列的定义

2.2循环队列定义

2.3循环队列的基本操作

三、队列的链式储存结构

3.1链队列的定义

3.2链队列的基本操作


一、队列的定义

队列是一种线性表,其特殊性在于队列的基本操作是线性表的子表。队列按先进先出的规则进行操作,故称其为操作受限的线性表。

队列(queue)是只允许在一端进行插入操作,在另一端进行删除操作的线性表,简称“队”。

允许插入的一端称为队尾(rear),允许删除的一端称为队头(front)

向队列中插入新的数据元素称为入队,新入队的元素就成为了队列的队尾元素。

从队列中删除队头元素称为出队,其后继元素成为新的队头元素。

注:出队的方向应该与入队的方向一致。

以下为一个简单的队列实现代码:

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义队列结构体
typedef struct {int items[MAX_SIZE];int front;int rear;
} Queue;// 初始化队列
void initQueue(Queue *q) {q->front = -1;q->rear = -1;
}// 检查队列是否为空
int isEmpty(Queue *q) {return q->front == -1;
}// 检查队列是否已满
int isFull(Queue *q) {return (q->rear == MAX_SIZE - 1);
}// 入队操作
void enqueue(Queue *q, int value) {if (isFull(q)) {printf("Queue is full\n");return;}if (q->front == -1) {q->front = 0;}q->rear++;q->items[q->rear] = value;
}// 出队操作
int dequeue(Queue *q) {int item;if (isEmpty(q)) {printf("Queue is empty\n");return -1;}item = q->items[q->front];if (q->front == q->rear) {q->front = -1;q->rear = -1;} else {q->front++;}return item;
}int main() {Queue q;initQueue(&q);enqueue(&q, 10);enqueue(&q, 20);enqueue(&q, 30);printf("%d dequeued from queue\n", dequeue(&q));printf("%d dequeued from queue\n", dequeue(&q));return 0;
}

二、队列的顺序储存结构

队列作为一种特殊的线性表,也同样存在两种存储结构:顺序存储结构和链式存储结构,可以分别用数组和链表来实现队列。

2.1顺序队列的定义

用一组地址连续的存储单元,依次存放从队头到队尾的数据元素,称为顺序队列

需要附设两个指针:队头指针(front)队尾指针(rear),分别指向队头元素和队尾元素。

以下为实现代码:

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义队列结构体
typedef struct {int items[MAX_SIZE];int front;int rear;
} Queue;// 初始化队列
void initQueue(Queue *q) {q->front = 0;q->rear = -1;
}// 检查队列是否为空
int isEmpty(Queue *q) {return (q->rear < q->front);
}// 检查队列是否已满
int isFull(Queue *q) {return (q->rear == MAX_SIZE - 1);
}// 入队操作
void enqueue(Queue *q, int value) {if (isFull(q)) {printf("Queue is full\n");return;}q->rear++;q->items[q->rear] = value;
}// 出队操作
int dequeue(Queue *q) {int item;if (isEmpty(q)) {printf("Queue is empty\n");return -1;}item = q->items[q->front];q->front++;return item;
}// 获取队列长度
int queueLength(Queue *q) {if (isEmpty(q)) {return 0;}return (q->rear - q->front + 1);
}int main() {Queue q;initQueue(&q);enqueue(&q, 10);enqueue(&q, 20);enqueue(&q, 30);printf("%d dequeued from queue\n", dequeue(&q));printf("%d dequeued from queue\n", dequeue(&q));printf("Queue length: %d\n", queueLength(&q));return 0;
}

 

 接下来介绍在此过程中可能出现的假溢出的现象:

“假溢出”:如果在插入E的基础上再插入元素F,将会插入失败。因为rear==MAXSIZE,尾指针已经达到队列的最大长度。但实际上队列存储空间并未全部被占满,这种现象叫做“假溢出”。

假溢出的原因是顺序队列进行队头出队、队尾入队,造成数组前面会出现空闲单元未被充分利用。

 2.2循环队列的定义

为了解决可能出现的假溢出现象,使得队列中的储存空间可以得到充分利用,一个巧妙的方法就是使用循环队列的方法,将顺序队列看作一个头尾相接的循环结构。

故可以得出循环队列的定义是:队列头尾相接的顺序储存结构称为循环队列

循环队列的实现代码:

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义队列结构体
typedef struct {int items[MAX_SIZE];int front;int rear;int size;
} Queue;// 初始化队列
void initQueue(Queue *q) {q->front = 0;q->rear = -1;q->size = 0;
}// 检查队列是否为空
int isEmpty(Queue *q) {return (q->size == 0);
}// 检查队列是否已满
int isFull(Queue *q) {return (q->size == MAX_SIZE);
}// 入队操作
void enqueue(Queue *q, int value) {if (isFull(q)) {printf("Queue is full\n");return;}q->rear = (q->rear + 1) % MAX_SIZE;q->items[q->rear] = value;q->size++;
}// 出队操作
int dequeue(Queue *q) {int item;if (isEmpty(q)) {printf("Queue is empty\n");return -1;}item = q->items[q->front];q->front = (q->front + 1) % MAX_SIZE;q->size--;return item;
}int main() {Queue q;initQueue(&q);enqueue(&q, 10);enqueue(&q, 20);enqueue(&q, 30);printf("%d dequeued from queue\n", dequeue(&q));printf("%d dequeued from queue\n", dequeue(&q));return 0;
}

 

但是循环队列也是会出现问题:

问题:当循环对列为空或满时,都是队尾指针等于队头指针,即rear==front 。当rear==front时,该是判满还是判空呢?

解决方案:

方案一:设置一个计数器,开始时计数器设为0,新元素入队时,计数器加1,元素出队,计数器减1。当计数器==MAXSIZE时,队满;计数器==0时,队空。

方案二:保留一个元素空间,当队尾指针指的空闲单元的后继单元是队头元素所在单元时,队满。

队满的条件为(Q.rear+1)%MAXSIZE==Q.front;

队空的条件为  Q.rear==Q.front

2.3循环队列的基本操作

typedef int ElemType
#define MAXSIZE 1024/*循环队列的顺序存储结构*/
typedef struct
{ElemType data[MAXSIZE];int front;    //头指针int rear;    //尾指针
}SqQueue;/*初始化一个空队列*/
int Init_SeQueue(SeQueue *Q)
{Q=(SeQueue *)malloc(sizeof(SeQueue));if(Q!=NULL){Q->front=0;Q->rear=0;}return 1;
}/*求队列长度*/
int QueueLength(SeQueue *Q)
{return (Q->rear-Q->front+MAXSIZE)%MAXSIZE;
}/*判空*/
int SeQueue_Empty(SeQueue *Q)
{return Q->rear==Q->front;
}/*判满*/
int SeQueue_Full(SeQueue *Q)
{return (Q->rear+1)%MAXSIZE==Q->front;
}/*入队操作*/
int Enter_SeQueue(SeQueue *Q,ElemType e)
{if(SeQueue_Full(Q)){return 0;}Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;return 1;
}/*出队操作*/
int Delete_SeQueue(SeQueue *Q,ElemType e)
{if(SeQueue_Empty(Q)){return 0;}e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;return 1;
}

三、队列的链式存储结构

3.1链队列的定义

采用链式储存结构的队列称为链队列。

为了使操作更加方便,将队头指针指向链队列的头结点,而队尾指针指向终端结点。 

空队列时,front和rear都指向头结点,即front==rear

代码实现链队列结构:

typedef int ElemType/*结点结构*/
typedef struct QNode
{ElemType data;struct QNode *next;
}QNode,*QueuePtr;/*链队列结构*/
typedef struct 
{QueuePtr front,rear;//队头、队尾指针
}LinkQueue;

3.2链队列的基本操作

typedef int ElemType/*结点结构*/
typedef struct QNode
{ElemType data;struct QNode *next;
}QNode,*QNodePtr;/*链队列结构*/
typedef struct 
{QNodePtr front,rear;//队头、队尾指针
}LinkQueue,*LinkQueuePtr;/*初始化一个空队列*/
int Init_LinkQueue(LinkQueuePtr Q)
{Q=(LinkQueuePtr)malloc(sizeof(LinkQueue));QNodePtr head=(QueuePtr)malloc(sizeof(QNode));if(head!=NULL && Q!=NULL){head->next=NULL;Q->front=head;Q->rear=head;}return 1;
}/*判空*/
int LinkQueue_Empty(LinkQueuePtr Q)
{return Q->front==Q->rear;
}/*入队操作*/
int Enter_LinkQueue(LinkQueuePtr Q,ElemType e)
{QNodePtr s=(QNodePtr)malloc(sizeof(QNode));if(s==NULL){return 0}    //初始化新结点s->data=e;s->next=NULL;//建立新联系Q->rear->next=s;Q->rear=s;return 1;
}/*出队操作*/
int Delte_LinkQueue(LinkQueuePtr Q,ElemType *e)
{QNodePtr p;if(LinkQueue_Empty(Q)){return 0} //保留删除结点的信息p=Q->front->next;*e=p->data;//建立新联系Q->front->next=p->next;if(Q->rear==p){Q->rear=Q->front)}free(p);return 1;
}

以上就是有关队列的知识及代码实现。

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

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

相关文章

【计算机网络】实验2:总线型以太网的特性

实验 2&#xff1a;总线型以太网的特性 一、 实验目的 加深对MAC地址&#xff0c;IP地址&#xff0c;ARP协议的理解。 了解总线型以太网的特性&#xff08;广播&#xff0c;竞争总线&#xff0c;冲突&#xff09;。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实…

PHP RabbitMQ连接超时问题

问题背景 Error: The connection timed out after 3 sec while awaiting incoming data 看到这个报错&#xff0c;我不以为意&#xff0c;认为是我设置的超时时间不够导致的&#xff0c;那就设置长一点 Error: The connection timed out after 300 sec while awaiting incom…

asp.net core过滤器应用

筛选器类型 授权筛选器 授权过滤器是过滤器管道的第一个被执行的过滤器&#xff0c;用于系统授权。一般不会编写自定义的授权过滤器&#xff0c;而是配置授权策略或编写自定义授权策略。简单举个例子。 using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCo…

缓存与数据库数据一致性 详解

缓存与数据库数据一致性详解 在分布式系统中&#xff0c;缓存&#xff08;如 Redis、Memcached&#xff09;与数据库&#xff08;如 MySQL、PostgreSQL&#xff09;一起使用是提高系统性能的常用方法。然而&#xff0c;缓存与数据库可能因更新时序、操作失误等原因出现数据不一…

Linux DNS解释器

作用 DNS&#xff08;Domain Name System&#xff09;是互联网上的一项服务&#xff0c;用于将域名和IP地址进行相互映射&#xff0c;使人 更方便的访问互联网 正向解析&#xff1a;域名->IP 反向解析&#xff1a;IP->域名 连接方式 DNS使用53端口监听网络 查看方法&a…

3.STM32通信接口之SPI通信---SPI实战(W25Q64存储模块介绍)《精讲》

上一节介绍了SPI的通信过程和方法&#xff0c;接下来就要进行STM32与外围模块通信了&#xff0c;这个模块是一块非易失型存储芯片&#xff0c;能够提供8MB的存储空间。接下来跟着Whappy脚步&#xff0c;进行探索新大陆吧&#xff01;【免费】W25Q64(中英文数据手册)资源-CSDN文…

嵌入式系统应用-LVGL的应用-平衡球游戏 part2

平衡球游戏 part2 4 mpu60504.1 mpu6050 介绍4.2 电路图4.3 驱动代码编写 5 游戏界面移植5.1 移植源文件5.2 添加头文件 6 参数移植6.1 4 mpu6050 4.1 mpu6050 介绍 MPU6050是一款由InvenSense公司生产的加速度计和陀螺仪传感器&#xff0c;广泛应用于消费电子、机器人等领域…

java将word docx pdf转换为图片(不需要额外下载压缩包,直接导入maven坐标)

(本代码实现的是将第1页转为图片&#xff0c;主要用于制作文件缩略图) pdf转图片容易 docx转图片麻烦&#xff0c;看其他博客可以直接导入maven坐标&#xff0c;但我知道那是需要付费且有时限的包 本着简单实用的心&#xff0c;我找到法子了 pdf转图片&#xff1a;有库直接转…

C#学写了一个程序记录日志的方法(Log类)

1.错误和警告信息单独生产文本进行记录&#xff1b; 2.日志到一定内存阈值可以打包压缩&#xff0c;单独存储起来&#xff0c;修改字段MaxLogFileSizeForCompress的值即可&#xff1b; 3.Log类调用举例&#xff1a;Log.Txt(JB.信息,“日志记录内容”,"通道1"); usi…

Qt—QLineEdit 使用总结

文章参考:Qt—QLineEdit 使用总结 一、简述 QLineEdit是一个单行文本编辑控件。 使用者可以通过很多函数,输入和编辑单行文本,比如撤销、恢复、剪切、粘贴以及拖放等。 通过改变 QLineEdit 的 echoMode() ,可以设置其属性,比如以密码的形式输入。 文本的长度可以由 m…

linux(centos) 环境部署,安装JDK,docker(mysql, redis,nginx,minio,nacos)

目录 1.安装JDK (非docker)1.1 将文件放在目录下&#xff1a; /usr/local/jdk1.2 解压至当前目录1.3 配置环境变量 2.安装docker2.1 验证centos内核2.2 安装软件工具包2.3 设置yum源2.4 查看仓库中所有docker版本&#xff0c;按需选择安装2.5 安装docker2.6 启动docker 并 开机…

电阻改善信号完整性

1.为什么电路端接电阻能改善信号完整性 由于电信号在PCB上传输&#xff0c;因此在PCB设计中可以把PCB走线认为是信号的通道&#xff0c;当该通道的 物理结构&#xff08;线宽&#xff0c;线到参考面的距离等&#xff09;发生变化&#xff0c;特别是有一些突变时&#xff0c;都会…

Java基础面试题,46道Java基础八股文(4.8万字,30+手绘图)

Java是一种广泛使用的编程语言&#xff0c;由Sun Microsystems&#xff08;现为Oracle Corporation的一部分&#xff09;在1995年首次发布。它是一种面向对象的语言&#xff0c;这意味着它支持通过类和对象的概念来构造程序。 Java设计有一个核心理念&#xff1a;“编写一次&am…

redisson-spring-data与Spring-Data-Redis的版本关系问题

redisson-spring-boot-starter https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter https://github.com/redisson/redisson/tree/master/redisson-spring-data#spring-data-redis-integration 将 Redisson 与 Spring Boot 库集成。依赖于Spring…

记录下nginx接口代理配置问题

其中api和api1是前面定义的upstream&#xff0c;ip相同只是端口不同。 一开始/api1/直接 像api一样 proxy_pass http://api1这样是不行的&#xff0c;因为会代理到 后端的 /api1/...接口&#xff0c;而后端实际接口地址是 /api/..... 所以必须像上面写法才能将外网的 /api…

高效流程图绘制:开发设计流程图利器

在选择画流程图的工具时&#xff0c;不同的项目和使用场景会决定最佳的工具。以下是几款常见的流程图工具&#xff0c;并结合具体项目使用场景提供建议&#xff1a; 1. Lucidchart 特点&#xff1a; 在线协作&#xff1a;支持多人实时协作&#xff0c;适合团队合作。模板丰富&…

【Python网络爬虫笔记】7-网络爬虫的搜索工具re模块

目录 一、网络爬虫中的正则表达式和re模块&#xff08;一&#xff09;数据提取的精确性&#xff08;二&#xff09;处理复杂的文本结构&#xff08;三&#xff09;提高数据处理效率 二、正则表达式的内涵&#xff08;一&#xff09;、常用元字符&#xff08;二&#xff09;、量…

2411mfc,修改按钮颜色

添加消息:ON_WM_CTLCOLOR() //在OnInitDialog()方法中添加{HWND hSatateWnd GetDlgItem(IDC_CHK)->GetSafeHwnd();SetWindowTheme(hSatateWnd, _T(""), _T(""));}头文件中: afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);HBRUSH O…

python(18) : flask_sqlalchemy 配置sqlserver数据库对象

1.安装依赖 pip3 install flask_sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ requests2.数据库配置信息(db_manager.py) import osfrom flask import Flask from flask_cors import CORS from flask_sqlalchemy import SQLAlchemydatabase testapp Flask(__nam…

3248. 矩阵中的蛇

3248. 矩阵中的蛇 题目链接&#xff1a;3248. 矩阵中的蛇 代码如下&#xff1a; class Solution { public:int finalPositionOfSnake(int n, vector<string>& commands){int i 0, j 0;for (string& command : commands){if (command "LEFT") { j…