【数据结构】线性表----队列详解

1. 队列的基本概念

话不多说,直接开始!

队列是一种线性数据结构,同栈类似但又不同,遵循先进先出FIFO, First In First Out)的原则。换句话说,最先进入队列的元素会最先被移除。这样的特点使得队列非常适合用于需要按顺序处理任务的场景。
在这里插入图片描述

特点:

  • 先进先出:第一个进入队列的元素最先被处理。
  • 操作受限:元素只能从队尾插入,从队头移除。
2. 队列的实现

在这里插入图片描述

队列可以通过多种方式实现,常见的有数组和链表两种。

使用数组实现队列:
使用数组实现队列需要维护两个指针,分别指向队头和队尾,并且需要处理数组的溢出问题。所以数组不是很适合用来实现队列。

使用链表实现队列:
链表不会受到同数组一样的困扰,并且链表实现的队列没有数组的大小限制;但需要额外的指针来管理链表的节点。

4. 队列的基本操作

队列的基本操作包括入队(Enqueue)出队(Dequeue)查看队头(Peek)检查队列是否为空(IsEmpty)

入队(Enqueue):
将元素添加到队尾。

出队(Dequeue):
移除队头的元素。

查看队头(Peek):
查看队头的元素,但不移除。

检查队列是否为空(IsEmpty):
检查队列中是否有元素。

5. 队列的高级用法

循环队列:
循环队列是一种优化的队列实现,避免了数组实现中由于出队操作造成的空间浪费。

优先队列:
优先队列中的元素具有优先级,出队时优先级高的元素会被优先移除。

6.两种形式的队列实现

在这里插入图片描述

入队(Enqueue)

将元素添加到队尾。如果使用数组实现,需要检查队列是否已满。如果使用链表实现,只需将新节点添加到链表的末尾。

数组实现的入队操作:

void enqueue(Queue* q, int value) {
    if (isFull(q)) {
        printf("Queue is full!\n");
        return;
    }
    if (isEmpty(q)) {
        q->front = 0;
    }
    q->rear++;
    q->items[q->rear] = value;
}

链表实现的入队操作:

void enqueue(Queue* q, int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;
    if (isEmpty(q)) {
        q->front = newNode;
    } else {
        q->rear->next = newNode;
    }
    q->rear = newNode;
}
出队(Dequeue)

移除队头的元素。如果使用数组实现,需要检查队列是否为空,并调整队头指针。如果使用链表实现,需要移除链表的第一个节点。

数组实现的出队操作:

int dequeue(Queue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    }
    int item = q->items[q->front];
    q->front++;
    if (q->front > q->rear) {
        initQueue(q);
    }
    return item;
}

链表实现的出队操作:

int dequeue(Queue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    }
    int item = q->front->data;
    Node* temp = q->front;
    q->front = q->front->next;
    if (q->front == NULL) {
        q->rear = NULL;
    }
    free(temp);
    return item;
}
查看队头(Peek)

查看队头的元素,但不移除。如果队列为空,应返回特定的错误值或抛出异常。

数组实现的查看队头操作:

int peek(Queue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    }
    return q->items[q->front];
}

链表实现的查看队头操作:

int peek(Queue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    }
    return q->front->data;
}
检查队列是否为空(IsEmpty)

检查队列中是否有元素。这是一个常用的辅助操作,用于确保其他操作的前提条件。

数组实现的检查是否为空操作:

int isEmpty(Queue* q) {
    return q->front == -1;
}

链表实现的检查是否为空操作:

int isEmpty(Queue* q) {
    return q->front == NULL;
}

队列的高级玩法

除了基本操作外,队列还有一些高级用法,如循环队列和优先队列。

循环队列

在这里插入图片描述

循环队列是一种优化的队列实现,避免了数组实现中由于出队操作造成的空间浪费。循环队列通过将队尾连接到队头,使得数组能够循环使用。

循环队列的实现:

#define MAX 100

typedef struct {
    int items[MAX];
    int front, rear;
} CircularQueue;

void initQueue(CircularQueue* q) {
    q->front = -1;
    q->rear = -1;
}

int isEmpty(CircularQueue* q) {
    return q->front == -1;
}

int isFull(CircularQueue* q) {
    return (q->rear + 1) % MAX == q->front;
}

void enqueue(CircularQueue* q, int value) {
    if (isFull(q)) {
        printf("Queue is full!\n");
        return;
    }
    if (isEmpty(q)) {
        q->front = 0;
    }
    q->rear = (q->rear + 1) % MAX;
    q->items[q->rear] = value;
}

int dequeue(CircularQueue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    }
    int item = q->items[q->front];
    if (q->front == q->rear) {
        initQueue(q);
    } else {
        q->front = (q->front + 1) % MAX;
    }
    return item;
}
优先队列

优先队列中的元素具有优先级,出队时优先级高的元素会被优先移除。优先队列可以使用**堆(Heap)**来实现,能够高效地进行插入和删除操作。
而堆我们将会在下一章进行讲解。

队列在实际中的应用

队列在许多实际应用中扮演重要角色,以下是几个常见的例子:

操作系统中的任务调度

操作系统使用队列管理任务的执行顺序。任务调度器将所有待处理的任务放入队列中,并按顺序调度这些任务。

打印队列

打印机使用队列管理打印任务,确保按顺序打印。

广度优先搜索(BFS)

在图的遍历中,BFS使用队列管理待访问的节点。BFS是一种图的遍历算法,它从根节点开始,先访问所有相邻节点,再按层次访问更深的节点。

使用队列时需要注意的问题

  1. 空间复杂度: 数组实现的队列在入队和出队操作后可能会导致空间浪费,使用循环队列可以解决这个问题。
  2. 时间复杂度: 队列的基本操作时间复杂度通常为O(1),但优先队列的插入和删除操作可能会更耗时,具体取决于实现方式。
  3. 内存管理: 使用链表实现队列时,需要注意内存管理,确保在出队操作后释放已移除节点的内存,避免内存泄漏。

总结

队列作为一种重要的数据结构,具有简单但实用的特性。在本文中,我们介绍了队列的基本概念、实现方法、常见操作、实际应用以及使用时需要注意的问题。通过实践代码示例,相信读者能更好地理解和掌握队列的使用。队列在编程中的应用广泛,相信掌握了它将为你的编程技能打下坚实的基础。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Spring Cloud精英指南】深度探索与实战:网关Gateway的高级应用与最佳实践

1. 前言 Spring Cloud Gateway提供了一个在Spring生态系统之上构建的API网关,包括:Spring 5,Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的路由方式,并为它们提供一些网关基本功能,…

IntelliJ IDEA 2024.1.4最新教程!!直接2099!!爽到飞起!!

IntelliJ IDEA 2024.1.4最新破解教程!!直接2099!!爽到飞起!!【资源在末尾】安装馆长为各位看官准备了多个版本,看官可根据自己的需求进行下载和选择安装。https://mp.weixin.qq.com/s/Tic1iR_Xc…

C语言-顺序表

🎯引言 欢迎来到HanLop博客的C语言数据结构初阶系列。在这个系列中,我们将深入探讨各种基本的数据结构和算法,帮助您打下坚实的编程基础。本次我将为你讲解。顺序表(也称为数组)是一种线性表,因其简单易用…

常用录屏软件,分享这四款宝藏软件!

在数字化时代,录屏软件已经成为我们日常工作、学习和娱乐中不可或缺的工具。无论你是需要录制教学视频、游戏过程,还是进行产品演示,一款高效、易用的录屏软件都能让你的工作事半功倍。今天,就为大家揭秘四款宝藏级录屏软件&#…

Ajax从零到实战

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

性价比高充电宝有哪些?充电宝十大最佳品牌大盘点!

在如今这个高度数字化的时代,我们的生活离不开各种电子设备,而充电宝作为保障电子设备续航的重要工具,其地位日益凸显。然而,面对市场上琳琅满目的充电宝品牌和产品,要挑选到一款性价比高的充电宝并非易事。在这篇盘点…

java使用easypoi模版导出word详细步骤

文章目录 第一步、引入pom依赖第二步、新建导出工具类WordUtil第三步、创建模版word4.编写接口代码5.导出结果示例 第一步、引入pom依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><…

element-ui操作表格行内容如何获取当前行索引?

需求&#xff1a; 根据每个用户的提交次数、撤回次数&#xff0c;动态计算出实际次数&#xff0c;并且提交次数不能小于撤回次数 <template><div><el-table:data"tableData"style"width: 80%"border><el-table-columnprop"date&…

【IOS】React Native之HelloWorld

RN搭建开发环境 rvm 安装3.2.2 brew install node18 brew install watchman# 使用nrm工具切换淘宝源 npx nrm use taobao# 如果之后需要切换回官方源可使用 npx nrm use npmnpm install -g yarnbrew install cocoapodsnpm uninstall -g react-native-cli react-native-communi…

(c#实现)决策树算法原理和案例

一、引言 决策树&#xff08;Decision Tree&#xff09;是一种常用的监督学习算法&#xff0c;广泛应用于分类和回归任务。它的直观性和可解释性使其成为机器学习和数据挖掘领域的重要工具。本文将详细介绍决策树的原理&#xff0c;并通过一个实际案例展示如何使用C#实现决策树…

【MindSpore学习打卡】应用实践-LLM原理和实践-基于MindSpore实现BERT对话情绪识别

在当今的自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情绪识别是一个非常重要的应用场景。无论是在智能客服、社交媒体分析&#xff0c;还是在情感计算领域&#xff0c;准确地识别用户的情绪都能够极大地提升用户体验和系统的智能化水平。BERT&#xff08;Bidirec…

C++类和对象学习笔记

1.类的定义 1.1类定义的格式 class是定义类的关键字&#xff0c;Date为类的名字&#xff0c;{ }中为类的主体&#xff0c;注意定义类结束时后面的分号不能省略。类中的内容称为类的成员&#xff1b;类中的变量称为类的属性或成员变量&#xff1b;类中的函数称为类的方法或者成…

jdk1.8安装教程及环境变量配置(含jdk8,11,13安装文件)

目录 友情提醒第一章、JVM、JRE、JDK介绍第二章、下载和安装JDK2.1&#xff09;百度网盘直接下载免安装2.2&#xff09;官网下载安装JDK&#xff08;需要收费&#xff09; 第三章、环境变量配置3.1&#xff09;windows环境变量配置3.2&#xff09;验证环境变量是否配置成功 友情…

类和对象——【运算符重载】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件iostream的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

PDA:Prompt-based Distribution Alignment for Unsupervised Domain Adaptation

文章汇总 式中&#xff0c; y s y^s ys表示源域数据的one-hot ground-truth&#xff0c; K K K为类数&#xff0c; w i w_i wi​和 z ~ s \tilde{z}_s z~s​分别表示源域经过提示调优的最终文本表示和最终图像表示的第 i i i类。 同理&#xff0c;为了进一步利用目标领域的数据…

ARMV8安全特性:Pointer Authentication

文章目录 前言一、Introduction二、Problem Definition三、Pointer Authentication3.1 Instructions3.2 Cryptography3.3 Key Management 四、Sample Use Cases4.1 Software Stack Protection4.2 Control Flow Integrity (CFI)4.3 Binding Pointers to Addresses 五、Security …

B2B领域的客户裂变策略:打造行业内的共赢生态

在日益竞争激烈的B2B市场中&#xff0c;客户裂变作为一种高效的增长策略&#xff0c;不仅能够帮助企业快速扩大客户基础&#xff0c;还能促进行业内资源共享与合作&#xff0c;共同构建一个健康、可持续的共赢生态。本文将探讨B2B领域实施客户裂变策略的关键要素&#xff0c;以…

【数据结构】排序——快速排序

前言 本篇博客我们继续介绍一种排序——快速排序&#xff0c;让我们看看快速排序是怎么实现的 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 ​ 目录 …

“学习Pandas中时间序列的基本操作“

目录 # 开篇 1. 创建和操作时间序列对象 2. 时间序列数据的读取和存储 3. 时间序列数据的索引和切片 4. 时间序列数据的操作和转换 5. 时间序列数据的可视化 6. 处理时间序列中的缺失值 7. 时间序列数据的聚合和分组 8. 时间序列的时间区间和偏移量操作 示例代码&…