【数据结构】线性表(十)队列:循环队列及其基本操作(初始化、判空、判满、入队、出队、存取队首元素)

文章目录

  • 队列
    • 1. 定义
    • 2. 基本操作
  • 顺序队列
  • 循环队列
    • 1. 头文件和常量
    • 2. 队列结构体
    • 3. 队列的初始化
    • 4. 判断队列是否为空
    • 5. 判断队列是否已满
    • 6. 入队
    • 7. 出队
    • 8. 存取队首元素
    • 9. 获取队列中元素个数
    • 10. 打印队列中的元素
    • 9. 主函数
    • 10. 代码整合

  堆栈Stack 和 队列Queue是两种非常重要的数据结构,两者都是特殊的线性表:

  • 对于堆栈,所有的插入和删除(以至几乎所有的存取)都是在表的同一端进行;
  • 对于队列,所有的插入都是在表的一端进行,所有的删除(以至几乎所有的存取)都是在表的另一端进行。

队列

1. 定义

  队列是一种操作受限的线性表,对于它的所有插入都在表的一端进行,所有的删除(以至几乎所有的存取)都在表的另一端进行,且这些操作又都是按照先进先出(FIFO)的原则进行的。进行删除的一端称为队头(front),进行插入的一端称为队尾(rear)。没有元素的队列称为空队列(简称空队)。

在这里插入图片描述
  队列就像生活中排队购物,新来的人只能加入队尾(假设不允许插队),购物结束后先离开的总是队头(假设无人中途离队)。也就是说,先加入队列的成员总是先离开队列,因此队列被称为先进先出(First In First Out)的线性表,简称为FIFO表。如图,在空队列中依次加入元素a1,a2,a3,a4,a5,出队次序仍然是a1,a2,a3,a4,a5 .

2. 基本操作

  • 队列是受限的线性表,其基本操作包括

    • IsEmpty() : 判断队列是否为空;
    • isFull():判断队列是否为满;
    • enqueue() :向队尾添加元素(入队);
    • dequeue() :删除队首元素(出队);
    • peek():获取队首的元素值(存取);
  • 同普通线性表一样,队列也可以用顺序存储和链接存储两种方式来实现:

顺序队列

  参考前文:线性表(八)队列:顺序队列及其基本操作(初始化、判空、判满、入队、出队、存取队首元素)

  关于顺序队列,删除队头元素有两种方式:

  • ⑴ 不要求队头元素必须存放在数组的第一个位置。每次删除队头元素,只需修改队头指针front所指的位置(即队头元素在数组中的下标),令front=front+1 . 该方式的优点是无须改变诸队列元素的地址,缺点是front值随着队头元素的删除而不断增加,整个队列向数组的后端位置移动,随着队尾元素的不断加入,必然出现数组后端没有可用空间的情况,而数组前端的大量空间却被闲置。
  • ⑵ 要求队头元素必须存放在数组的第一个位置。每次删除队头元素,令所有元素都向前移动一个位置。该方式的优点是不浪费空间,缺点是所有元素的地址都必须改变,效率低下。

循环队列

  为了克服上述缺点,可以假定数组是循环的,即采用环状模型来实现顺序队列。这种模型将队列在逻辑上置于一个圆环上,如图3.17所示,用整型变量front存放队头位置,每删除一个队头元素,就将front顺时针移动一个位置;整型变量rear存放新元素要插入的位置(下标),每插入一个元素,rear将顺时针移动一个位置;整型变量count存放队列中元素的个数,当count等于数组规模Size时,说明队列已满,当count等于0时,说明队列为空。
在这里插入图片描述

1. 头文件和常量

#include <stdio.h>
#define MAX_SIZE 100
  • 头文件stdio.h用于输入输出操作

  • 通过#define指令定义了一个常量MAX_SIZE,它表示顺序队列中数组的最大容量为100

2. 队列结构体

typedef struct {int data[MAX_SIZE]; // 存储队列元素的数组int front;          // 队头指针int rear;           // 队尾指针int count;          // 队列规模
} CircularQueue;
  • 整型数组 data,用于存储队列元素;
  • frontrear 分别表示队头指针和队尾指针;
  • count:队列中元素的个数。

3. 队列的初始化

void initQueue(CircularQueue *queue) {queue->front = 0;queue->rear = 0;queue->count = 0;
}

   initQueue 函数:初始化队列,它将队头、队尾和元素个数都设置为0,表示队列为空。

4. 判断队列是否为空

bool isEmpty(CircularQueue *queue) {
//    return queue->front == 0;return queue->count == 0;
}

   通过检查队列中元素的个数来判断队列是否为空。

5. 判断队列是否已满

bool isFull(CircularQueue *queue) {return queue->count == MAX_SIZE;
}

  通过比较队列中元素的个数和最大容量 MAX_SIZE 来判断队列是否已满。

6. 入队

void enqueue(CircularQueue *queue, int item) {if (isFull(queue)) {printf("Queue is full. Cannot enqueue.\n");return;}queue->data[queue->rear] = item;queue->rear = (queue->rear + 1) % MAX_SIZE;queue->count++;
}
  • 判断队列是否已满
    • 如果已满则打印错误信息并返回;
    • 否则,将元素添加到队尾,并更新队尾指针和元素个数。

7. 出队

int dequeue(CircularQueue *queue) {if (isEmpty(queue)) {printf("Queue is empty. Cannot dequeue.\n");return -1;}int item = queue->data[queue->front];queue->front = (queue->front + 1) % MAX_SIZE;queue->count--;return item;
}
  • 判断队列是否为空
    • 如果为空则打印错误信息并返回 -1;
    • 否则,将队头元素返回,并更新队头指针和元素个数。

8. 存取队首元素

int peek(CircularQueue *queue) {if (isEmpty(queue)) {printf("Queue is empty. Cannot peek.\n");return -1;}return queue->data[queue->front];
}

   peek 函数用于查看队头元素,但不移除它。如果队列为空,则打印提示信息并返回 -1。

9. 获取队列中元素个数

int size(CircularQueue *queue) {return queue->count;
}

10. 打印队列中的元素

void display(CircularQueue *queue) {if (isEmpty(queue)) {printf("Queue is empty.\n");return;}printf("Queue elements: ");int i = queue->front;int count = 0;while (count < queue->count) {printf("%d ", queue->data[i]);i = (i + 1) % MAX_SIZE;count++;}printf("\n");
}
  • 如果队列为空,则打印提示信息;
  • 否则,使用循环遍历队列中的元素并逐个打印。

9. 主函数

int main() {CircularQueue queue;initQueue(&queue);enqueue(&queue, 1);enqueue(&queue, 2);enqueue(&queue, 3);display(&queue);printf("Queue size: %d\n", size(&queue));printf("Front element: %d\n", peek(&queue));dequeue(&queue);printf("Dequeued element.\n");display(&queue);printf("Queue size: %d\n", size(&queue));printf("Front element: %d\n", peek(&queue));return 0;
}

在这里插入图片描述

10. 代码整合

#include <stdio.h>#define MAX_SIZE 100typedef struct {int data[MAX_SIZE]; // 存储队列元素的数组int front;          // 队头指针int rear;           // 队尾指针int count;          // 队列规模
} CircularQueue;void initQueue(CircularQueue *queue) {queue->front = 0;queue->rear = 0;queue->count = 0;
}bool isEmpty(CircularQueue *queue) {
//    return queue->front == 0;return queue->count == 0;
}bool isFull(CircularQueue *queue) {return queue->count == MAX_SIZE;
}void enqueue(CircularQueue *queue, int item) {if (isFull(queue)) {printf("Queue is full. Cannot enqueue.\n");return;}queue->data[queue->rear] = item;queue->rear = (queue->rear + 1) % MAX_SIZE;queue->count++;
}int dequeue(CircularQueue *queue) {if (isEmpty(queue)) {printf("Queue is empty. Cannot dequeue.\n");return -1;}int item = queue->data[queue->front];queue->front = (queue->front + 1) % MAX_SIZE;queue->count--;return item;
}int peek(CircularQueue *queue) {if (isEmpty(queue)) {printf("Queue is empty. Cannot peek.\n");return -1;}return queue->data[queue->front];
}int size(CircularQueue *queue) {return queue->count;
}void display(CircularQueue *queue) {if (isEmpty(queue)) {printf("Queue is empty.\n");return;}printf("Queue elements: ");int i = queue->front;int count = 0;while (count < queue->count) {printf("%d ", queue->data[i]);i = (i + 1) % MAX_SIZE;count++;}printf("\n");
}int main() {CircularQueue queue;initQueue(&queue);enqueue(&queue, 1);enqueue(&queue, 2);enqueue(&queue, 3);display(&queue);printf("Queue size: %d\n", size(&queue));printf("Front element: %d\n", peek(&queue));dequeue(&queue);printf("Dequeued element.\n");display(&queue);printf("Queue size: %d\n", size(&queue));printf("Front element: %d\n", peek(&queue));return 0;
}

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

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

相关文章

结构体学习

struct是结构体关键字 我们用C语言中通常都是用关键字来定义类型变量。例如我们的整型变量&#xff0c;int book;是用整型关键字定义出来的。同样的&#xff0c;struct book同样是一个类型&#xff0c;不过我们叫他结构体。我认为的结构体的作用&#xff0c;无外乎是将一些毫…

文件打包下载excel导出和word导出

0.文件下载接口 请求 GET /pm/prj/menu/whsj/download/{affixId} 文件affixId多个id以逗号隔开。多个文件会以打包得形式。 1.Excel导出 1.0接口 POST 127.0.0.1:8400/pm/io/exportExcel/year-plan-table-workflow/report 参数 [{"org":"011","re…

JSX看着一篇足以入门

JSX 介绍 学习目标&#xff1a; 能够理解什么是 JSX&#xff0c;JSX 的底层是什么 概念&#xff1a; JSX 是 javaScriptXML(HTML) 的缩写&#xff0c;表示在 JS 代码中书写 HTML 结构 作用&#xff1a; 在 React 中创建 HTML 结构&#xff08;页面 UI 结构&#xff09; 优势&a…

HarmonyOS开发:Log工具类源码分析

前言 一转眼就十月中旬了&#xff0c;国庆的劲真大&#xff0c;到现在还未缓过来&#xff0c;以至于要更新的文章迟迟未发布&#xff0c;大家可以看到&#xff0c;最近一段时间的文章&#xff0c;都是关于HarmonyOS相关的&#xff0c;两个原因吧&#xff0c;一是我司有这样的任…

操作系统——死锁及其解决方案(p38-p41王道视频、课本ch6)

1.死锁的“知识框架”&#xff1a; 2.“预防死锁”——破坏死锁的4个必要条件: 3.避免死锁&#xff01;&#xff01;&#xff01;&#xff01;——必考&#xff1a;银行家算法 安全性算法描述&#xff1a; 4.“死锁的检测和解除”:

CVer从0入门NLP(一)———词向量与RNN模型

&#x1f34a;作者简介&#xff1a;秃头小苏&#xff0c;致力于用最通俗的语言描述问题 &#x1f34a;专栏推荐&#xff1a;深度学习网络原理与实战 &#x1f34a;近期目标&#xff1a;写好专栏的每一篇文章 &#x1f34a;支持小苏&#xff1a;点赞&#x1f44d;&#x1f3fc;、…

h5的扫一扫功能 (非微信浏览器环境下)

必须在 https 域名下才生效 <template><div><van-field label"服务商编码" right-icon"scan" placeholder"扫描二维码获取" click-right-icon"getCameras" /> <div class"scan" :style"{disp…

鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统项目背景

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…

2-MySQL的基本操作记录

1 数据库相关 -- --------------------表相关的---------- -- 查看字符集 show variables like %character%;show databases;# 创建数据库 create database test2;# 删除数据库 drop database test2; show databases;#查看当前使用的数据库 select database(); 2 用户相关 -…

CUDA学习笔记(九)Dynamic Parallelism

本篇博文转载于https://www.cnblogs.com/1024incn/tag/CUDA/&#xff0c;仅用于学习。 Dynamic Parallelism 到目前为止&#xff0c;所有kernel都是在host端调用&#xff0c;CUDA Dynamic Parallelism允许GPU kernel在device端创建调用。Dynamic Parallelism使递归更容易实现…

小游戏外包开发流程及费用

小游戏的开发流程和费用会因项目的规模、复杂性和所选技术平台而有所不同。以下是一般的小游戏开发流程和可能的费用因素&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 开发流程&#xff1a; 概念和…

分享画PAD图的软件-PADFlowChart

软件的可执行文件下载&#xff1a;PADFlowChart-exe.zip 如果有帮助望三联