队列的基本操作——常见队列的对比分析(c语言完整代码包含注释)

news2025/2/23 21:59:57

目录

一、队列

1.1基本概念

1.2基本操作

1.3 队列分类

1.3.1带头队列

1.3.2不带头队列

1.3.3 循环带头队列

1.3.4 循环不带头队列

1.3.5 总结

二、代码实现

2.1带头队列

2.2不带头队列

2.3循环带头队列

2.4循环不带头队列


一、队列

1.1基本概念

        队列(Queue)是一种常见的数据结构,它遵循先进先出(First In First Out, FIFO)的原则,类似于现实生活中排队等待的概念。在队列中,元素按照其插入的顺序排列,最先插入的元素将最先被移除。

  • 队列元素:队列中的每个元素称为一个队列元素,可以是任意类型的数据。
  • 队列头(front):队列的头部,即第一个元素所在的位置,通常用于删除元素操作。
  • 队列尾(rear):队列的尾部,即最后一个元素所在的位置,通常用于插入元素操作。

1.2基本操作

        队列的基本操作主要包括入队和出队两种操作,通过这两种操作可以实现对队列中元素的添加和移除。在使用队列时,需要注意保持操作的顺序,遵循 FIFO 的规则,以确保队列的正确性和有效性。

  • 入队(enqueue):将元素插入到队列的末尾,即在队尾添加一个新元素。

  • 出队(dequeue):从队列的头部移除一个元素,并返回该元素的值。

  • 判空(isEmpty):判断队列是否为空,即队列中是否有元素。

  • 判满(isFull):判断队列是否已满,即队列中的元素数量是否达到上限。

  • 获取队头元素(peek):查看队列头部的元素值,但不移除该元素。

  • 清空队列(clear):移除队列中的所有元素,使队列变为空队列。

  • 获取队列长度(size):返回队列中元素的数量。

1.3 队列分类

1.3.1带头队列

  • front 和 rear 的初始值:在带头的队列中,front 和 rear 的初始值通常都设置为 0,表示头结点的位置。
  • 插入元素:在带头的队列中,插入元素时,先将 rear 加一,再将元素插入到 rear 所指向的位置。
  • 删除元素:在带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。

1.3.2不带头队列

  • front 和 rear 的初始值:通常情况下,不带头的队列中,front 和 rear 的初始值都为 -1,表示队列为空。
  • 插入元素:在不带头的队列中,插入元素时,先将 rear 加一,再将元素插入到 rear 所指向的位置。
  • 删除元素:在不带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。

1.3.3 循环带头队列

  • front 和 rear 的初始值:通常情况下,front 和 rear 的初始值都为 0,表示队列为空。
  • 插入元素:先将 rear 加一,再将元素插入到 rear 所指向的位置。如果 rear 达到数组末尾,可以通过取余运算将 rear 置为 0,实现循环利用数组空间。
  • 删除元素:先将 front 加一,返回 front 指向的位置的元素。同样地,如果 front 达到数组末尾,可通过取余运算将 front 置为 0。
  • 判空条件:当 front 和 rear 的值相等时,表示队列为空。
  • 判满条件:当 (rear + 1) % 数组长度 等于 front 的值时,表示队列满。

1.3.4 循环不带头队列

  • front 和 rear 的初始值:通常情况下,front 和 rear 的初始值都为 -1,表示队列为空。
  • 插入元素:先将 rear 加一,再将元素插入到 rear 所指向的位置。如果 rear 达到数组末尾,可以通过取余运算将 rear 置为 0,实现循环利用数组空间。
  • 删除元素:在不带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。
  • 判空条件:当 front 和 rear 的值相等且等于 -1 时,表示队列为空。
  • 判满条件:当 (rear + 1) % 数组长度 等于 front 的值时,表示队列满。

1.3.5 总结

        总的来说,循环队列带头和不带头在判满和判空上的逻辑是相同的,都是根据指针的位置关系来判断队列状态;而引入头结点的主要作用是简化队列为空和队列满的判断逻辑,使队列操作更加灵活高效。

二、代码实现

2.1带头队列

#include <stdio.h>
#include <stdlib.h>

#define SIZE 5


// 定义一个Queue结构体表示队列
typedef struct {
    int items[SIZE];
    int front;   // 队列头指针,指向头结点
    int rear;    // 队列尾指针,指向最后一个元素
} Queue;

// 创建一个空队列并返回其指针
Queue* createQueue() {
    Queue *queue = (Queue*)malloc(sizeof(Queue)); // 为队列分配内存
    queue->front = 0; // 初始化队列头指针
    queue->rear = 0; // 初始化队列尾指针
    return queue;
}

// 判断队列是否满了
int isFull(Queue *queue) {
    return (queue->rear == SIZE); // 如果队列尾指针指向最后一个元素的下一个位置,则队列已满
}

// 判断队列是否为空
int isEmpty(Queue *queue) {
    return (queue->front == queue->rear); // 如果队列头指针和尾指针相等,说明队列为空
}

// 将元素添加到队列尾部
void enqueue(Queue *queue, int item) {
    if (isFull(queue)) { // 如果队列已满,打印提示信息
        printf("队列已满,无法入队。\n");
    } else {
        queue->rear++; // 队列尾指针加1
        queue->items[queue->rear - 1] = item; // 将元素存储到队列尾部
        printf("%d 入队成功。\n", item); // 打印添加成功信息
    }
}

// 从队列头部移除一个元素并返回其值
int dequeue(Queue *queue) {
    int item;
    if (isEmpty(queue)) { // 如果队列为空,打印提示信息并返回-1表示操作失败
        printf("队列为空,无法出队。\n");
        return -1;
    } else {
        item = queue->items[queue->front]; // 获取队列头部元素的值
        queue->front++; // 队列头指针加1
        printf("%d 出队成功。\n", item); // 打印移除成功信息
        return item; // 返回移除的元素值
    }
}

int main() {
    Queue *queue = createQueue(); // 创建一个新的队列并获取其指针

    // 进行入队列和出队列操作
    enqueue(queue, 10);
    enqueue(queue, 20);
    enqueue(queue, 30);

    dequeue(queue);
    dequeue(queue);
    dequeue(queue);
    dequeue(queue); // 尝试从空队列中出队列

    free(queue); // 释放队列内存空间

    return 0;
}

2.2不带头队列

#include <stdio.h>
#include <stdlib.h>

#define SIZE 5


// 定义一个Queue结构体表示队列
typedef struct {
    int items[SIZE]; // 存储队列元素的数组
    int front; // 队列头指针
    int rear; // 队列尾指针
} Queue;


// 创建一个空队列并返回其指针
Queue* createQueue() {
    Queue *queue = (Queue*)malloc(sizeof(Queue)); // 为队列分配内存
    queue->front = -1; // 初始化队列头指针
    queue->rear = -1; // 初始化队列尾指针
    return queue;
}

// 判断队列是否满了
int isFull(Queue *queue) {
    return (queue->rear == SIZE - 1); // 如果队列尾指针指向最后一个元素,则队列已满
}


// 判断队列是否为空
int isEmpty(Queue *queue) {
    return (queue->front == -1 || queue->front > queue->rear); // 如果队列头指针指向了最后一个元素(队列为空),或指向的元素已经被出队列了,说明队列为空
}


// 将元素添加到队列尾部
void enqueue(Queue *queue, int item) {
    if (isFull(queue)) { // 如果队列已满,打印提示信息
        printf("队列已满,无法入队。\n");
    } else {
        if (queue->front == -1) { // 如果队列为空,将队列头指针设置为0
            queue->front = 0;
        }
        queue->rear++; // 队列尾指针加1
        queue->items[queue->rear] = item; // 将元素存储到队列尾部
        printf("%d 入队成功。\n", item); // 打印添加成功信息
    }
}


// 从队列头部移除一个元素并返回其值
int dequeue(Queue *queue) {
    int item;
    if (isEmpty(queue)) { // 如果队列为空,打印提示信息并返回-1表示操作失败
        printf("队列为空,无法出队。\n");
        return -1;
    } else {
        item = queue->items[queue->front]; // 获取队列头部元素的值
        queue->front++; // 队列头指针加1
        printf("%d 出队成功。\n", item); // 打印移除成功信息
        return item; // 返回移除的元素值
    }
}


int main() {
    Queue *queue = createQueue(); // 创建一个新的队列并获取其指针

    // 进行入队列和出队列操作
    enqueue(queue, 10);
    enqueue(queue, 20);
    enqueue(queue, 30);

    dequeue(queue);
    dequeue(queue);
    dequeue(queue);
    dequeue(queue); // 尝试从空队列中出队列

    free(queue); // 释放队列内存空间

    return 0;
}

2.3循环带头队列

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 4     // 队列的最大容量,带头

// 循环队列结构体
typedef struct {
    int data[MAX_SIZE];  // 用数组存储队列元素
    int front;           // 队头指针
    int rear;            // 队尾指针
} CircularQueue;

// 初始化循环队列
void initQueue(CircularQueue *queue) {
    queue->front = 0;    // 初始时队头指针指向第一个元素
    queue->rear = 0;     // 初始时队尾指针指向第一个元素
}

// 判断队列是否为空
int isEmpty(CircularQueue *queue) {
    return queue->front == queue->rear;  // 队列为空时,队头指针与队尾指针相等
}

// 判断队列是否已满
int isFull(CircularQueue *queue) {
    return (queue->rear + 1) % MAX_SIZE == queue->front;  // 队列已满时,队尾指针的下一个位置为队头指针
}

// 入队操作
void enqueue(CircularQueue *queue, int item) {
    if (isFull(queue)) {  // 判断队列是否已满
        printf("队列已满,无法插入新元素\n");
    } else {
        queue->data[queue->rear] = item;  // 将新元素插入队尾
        queue->rear = (queue->rear + 1) % MAX_SIZE;  // 移动队尾指针的位置
        printf("入队成功: %d\n", item);
    }
}

// 出队操作
int dequeue(CircularQueue *queue) {
    int item;
    if (isEmpty(queue)) {  // 判断队列是否为空
        printf("队列为空,无法出队\n");
        return -1;
    } else {
        item = queue->data[queue->front];  // 取出队头元素
        queue->front = (queue->front + 1) % MAX_SIZE;  // 移动队头指针的位置
        printf("出队元素: %d\n", item);
        return item;
    }
}

// 主函数
int main() {
    CircularQueue queue;
    initQueue(&queue);  // 初始化循环队列

    enqueue(&queue, 1);  // 入队操作
    enqueue(&queue, 2);
    enqueue(&queue, 3);
    enqueue(&queue, 3);

    dequeue(&queue);  // 出队操作
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);

    return 0;
}

2.4循环不带头队列

#include <stdio.h>

#define MAX_SIZE 5

// 定义循环队列结构体,不带头
typedef struct {
    int data[MAX_SIZE];  // 用数组存储队列元素
    int front;           // 队头指针
    int rear;            // 队尾指针
} CircularQueue;

// 初始化循环队列
void initQueue(CircularQueue *queue) {
    queue->front = -1;
    queue->rear = -1;
}

// 判断队列是否为空
int isEmpty(CircularQueue *queue) {
    return (queue->front == -1 && queue->rear == -1);
}

// 判断队列是否已满
int isFull(CircularQueue *queue) {
    return ((queue->rear + 1) % MAX_SIZE == queue->front);
}

// 入队操作
void enqueue(CircularQueue *queue, int value) {
    if (isFull(queue)) {
        printf("队列已满,无法入队。\n");
    } else if (isEmpty(queue)) {
        queue->front = 0;
        queue->rear = 0;
        queue->data[queue->rear] = value;
        printf("%d 入队成功。\n", value);
    } else {
        queue->rear = (queue->rear + 1) % MAX_SIZE;
        queue->data[queue->rear] = value;
        printf("%d 入队成功。\n", value);
    }
}

// 出队操作
int dequeue(CircularQueue *queue) {
    if (isEmpty(queue)) {
        printf("队列为空,无法出队。\n");
        return -1;
    } else {
        int value = queue->data[queue->front];
        if (queue->front == queue->rear) {
            queue->front = -1;
            queue->rear = -1;
        } else {
            queue->front = (queue->front + 1) % MAX_SIZE;
        }
        printf("%d 出队成功。\n", value);
        return value;
    }
}

int main() {
    CircularQueue queue;
    initQueue(&queue);

    // 入队操作
    enqueue(&queue, 10);
    enqueue(&queue, 20);
    enqueue(&queue, 30);
    enqueue(&queue, 40);
    enqueue(&queue, 50);
    enqueue(&queue, 60);  // 队列已满,无法入队

    // 出队操作
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);  // 队列已空,无法出队

    return 0;
}

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

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

相关文章

85、字符串操作的优化

上一节介绍了在模型的推理优化过程中,动态内存申请会带来额外的性能损失。 Python 语言在性能上之所以没有c++高效,有一部分原因就在于Python语言将内存的动态管理过程给封装起来了,我们作为 Python 语言的使用者是看不到这个过程的。 这一点有点类似于 c++ 标准库中的一些…

VegaPrime 2013 VP2013

Vega Prime 2013 VegaPrime 2013 VP2013

并发编程(2)管程(悲观锁)

4 共享模型之管程 本章内容 共享问题synchronized线程安全分析Monitorwait/notify线程状态转换活跃性Lock 4.1 共享带来的问题 4.1.1 小故事 老王&#xff08;操作系统&#xff09;有一个功能强大的算盘&#xff08;CPU&#xff09;&#xff0c;现在想把它租出去&#xff…

Linux(ACT)权限管理

文章目录 一、 ATC简介二、 案例1. 添加测试目录、用户、组&#xff0c;并将用户添加到组2. 修改目录的所有者和所属组3. 设定权限4. 为临时用户分配权限5. 验证acl权限 6. 控制组的acl权限 一、 ATC简介 ACL&#xff08;Access Control List&#xff0c;访问控制列表&#xf…

运维SRE-15 自动化批量管理-ansible1

## 1.什么是自动化批量管理重复性工作与内容: 思考如何自动化完成. 部署环境,批量查看信息,批量检查:自动化 一般步骤:1.如何手动实现2.如何自动化管理工具&#xff0c;批量实现3.注意事项&#xff1a;想要自动化一定要先标准化(所有环境&#xff0c;软件&#xff0c;目录一致)…

Vant轮播多个div结合二维数组的运用

需求说明 在开发H5的时候&#xff0c;结合Vant组件的轮播组件Swipe实现如下功能。我们查阅vant组件库官方文档可以得知&#xff0c;每个SwipeItem组件代表一个卡片&#xff0c;实现的是每屏展示单张图片或者单个div轮播方式&#xff0c;具体可以查阅&#xff1a;Vant 2 - 轻量、…

springboot750人职匹配推荐系统

springboot750人职匹配推荐系统 获取源码——》公主号&#xff1a;计算机专业毕设大全

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(8)-Ant Design Blazor前端框架搭建

前言 前面的章节我们介绍了一些值得推荐的Blazor UI组件库&#xff0c;通过该篇文章的组件库介绍最终我选用Ant Design Blazor这个UI框架作为ToDoList系统的前端框架。因为在之前的工作中有使用过Ant Design Vue、Ant Design Angular习惯并且喜欢Ant Design设计规范和风格&…

学生成绩管理系统(C语言课设 )

这个学生成绩管理系统使用C语言编写&#xff0c;具有多项功能以方便管理学生信息和成绩。首先从文件中读取数据到系统中&#xff0c;并提供了多种功能&#xff08;增删改查等&#xff09;选项以满足不同的需求。 学生成绩管理系统功能: 显示学生信息增加学生信息删除学生信息…

如何解决服务器之间大量数据文件传输交换慢的问题?

在信息化时代&#xff0c;企业运营的核心之一便是服务器间的数据交换效率。数据流通的速度直接关系到业务的响应速度和企业的整体表现。然而&#xff0c;数据传输速度缓慢的问题时常成为企业发展的绊脚石&#xff0c;可能导致严重的业务损失。本文将深入探讨造成服务器数据传输…

【MySQL】如何理解索引(高频面试点)

一、前言 首先这个博客会介绍一些关于MySQL中索引的基本内容以及一些基本的语法&#xff0c;当然里面也会有些常见的面试题的解答。 二、关于索引 1、概念 索引是一种能够帮助MySQL高效的去磁盘检索数据的一种数据结构。在MySQL的Innodb存储引擎中呢&#xff0c;采用的是B树的…

software framwork

software framwork软件架构 软件架构&#xff0c;之前图没找到&#xff0c;随手画了一个啦&#xff0c;了解架构细分职能和工作任务&#xff1a; 下图&#xff0c;第一是客户端架构包项目&#xff0c;第二是服务端架构包项目 -----------------------------------------------…

Thymeleaf无法显示模板视图,加载页面显示404状态问题的解决方法

本篇文章主要讲解&#xff1a;Thymeleaf无法显示模板视图&#xff0c;加载页面显示404状态问题的解决方法 日期&#xff1a;2024年2月23日 作者&#xff1a;任聪聪 现象说明&#xff1a; 1.只返回输出模板的名称&#xff0c;如图&#xff1a; 2.显示报错信息&#xff1a; Whi…

数字化转型导师坚鹏:县域数字化转型案例研究

县域数字化转型案例研究 课程背景&#xff1a; 很多县级政府存在以下问题&#xff1a; 不清楚县域数字化转型的发展模式 不清楚县域数字化转型的成功案例 课程特色&#xff1a; 针对性强 实用性强 创新性强 学员收获: 学习县域数字化转型的发展模式。 学习县…

129.乐理基础-曾音程、减音程、等音程

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;128.乐理基础-五线谱-纯四度、纯五度-CSDN博客 上一个内容里练习的答案&#xff1a; 首先c1-重降e1&#xff0c;c1-升e1的时候&#xff0c;也都是三度&#xff0c;但距离肯定不一样这时该叫什么&#xff1f;如下图…

【Ucore 操作系统】3. 多道程序与分时多任务

文章目录 【 0. 引言 】0.1 上章回顾0.2 背景0.3 协作式操作系统0.4 抢占式操作系统0.3 进程小述0.3 本章任务 【 1. 多道程序放置与加载 】1.1 多道程序的放置1.2 多道程序的加载 【 2. 进程基础结构 】2.1 进程的概念2.2 进程的基本管理2.3 进程的分配 【 3. 多道程序与协作式…

开发个IDEA插件

开发IDEA一个插件&#xff0c;但是这个插件的功能是个大杂烩吧&#xff0c; 主要完成以下几个功能&#xff0c;方便组内开发人员提高效率。 1 网关会传过来登录人员的 一些核心字段&#xff0c;公司编码/用户编号/主岗。 因为存在多租户&#xff0c;所以经常要切换任务&…

【PostgreSQL】Windows安装PostgreSQL数据库图文详细教程

Windows安装PostgreSQL数据库图文详细教程 一、前言二、PostgreSQL简介三、软件下载四、安装步骤4.1 安装向导4.2 选择安装目录4.3 选择组件4.4 选择数据存放目录4.5 选择密码4.6 选择端口号4.7 等待安装完成4.8 取消勾选&#xff0c;安装完成 五、启动教程5.1 搜索pgAdmin4&am…

ChatGPT 4 教你完成学生表,教师表,课程表,选课表之间的SQL学习

数据源准备&#xff1a; # 学生表 create table student( sno varchar(10) primary key, #学号sname varchar(20), #姓名sage int(2), #年龄ssex varchar(5) #性别 ); #教师表 create table teacher( tno varchar(10) primary …

思维模型整合

思维模型整合 4P--- 4C思考模型能力圈模型 4P— 4C思考模型 在竞争激烈的今天&#xff0c;每个赛道都有众多可以为客户提供相同价值的对手&#xff0c;而赛道中的佼佼者之所以能打败大部分人&#xff0c;可能并不是他们能比别人更能讨好大众&#xff0c;而是因为在这个赛道它有…