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

目录

一、队列

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.mfbz.cn/a/404766.html

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

相关文章

RAW 编程接口 TCP 简介

一、LWIP 中 中 RAW API 编程接口中与 TCP 相关的函数 二、LWIP TCP RAW API 函数 三、LwIP_Periodic_Handle函数 LwIP_Periodic_Handle 函数是一个必须被无限循环调用的 LwIP支持函数&#xff0c;一般在 main函数的无限循环中调用&#xff0c;主要功能是为 LwIP各个模块提供…

由于找不到d3dx9_43.dll无法继续执行的解决方法,5种有效的方法

丢失d3dx9_43.dll文件可能会引发一系列运行问题&#xff0c;具体表现在哪些方面呢&#xff1f;首先&#xff0c;它是DirectX 9.0c的一个重要动态链接库文件&#xff0c;对于许多基于此版本DirectX开发的老旧或经典PC游戏至关重要。一旦缺失&#xff0c;可能导致这些游戏无法启动…

element ui 安装 简易过程 已解决

我之所以将Element归类为Vue.js&#xff0c;其主要原因是Element是&#xff08;饿了么团队&#xff09;基于MVVM框架Vue开源出来的一套前端ui组件。我最爱的就是它的布局容器&#xff01;&#xff01;&#xff01; 下面进入正题&#xff1a; 1、Element的安装 首先你需要创建…

基于Java+Selenium的WebUI自动化测试框架(一)---页面元素定位器

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

糖尿病性视网膜病变(DR)的自动化检测和分期

糖尿病性视网膜病变&#xff08;DR&#xff09;的自动化检测和分期 提出背景DR的阶段及其特征 历年解法计算机视觉方法多分类方法 新的解法深度学习方法迁移学习大模型多模型集成全流程分析 总结特征1&#xff1a;图像分割特征2&#xff1a;疾病分级特征3&#xff1a;治疗建议生…

二进制中-1加上+1如果按照原码相加会存在什么问题?

问题描述&#xff1a;二进制中-1加上1如果按照原码相加会存在什么问题&#xff1f; 问题解答&#xff1a; -1加1等于-2&#xff0c;这明显是不对的。 因此引入反码的概念 然后再将计算后反码在取反码&#xff0c;得到-0&#xff0c;如下图所示。 -0不太精确&#xff0c;因此再…

美团面试:说说Java OOM的三大场景和解决方案?

美团面试&#xff1a;说说Java OOM的场景和解决方案&#xff1f; 尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&…

day05_方法

今日内容 流程控制关键字 break,continue方法 复习 1 循环的四要素 初始值控制条件循环内容迭代 2 for循环执行流程 for(初始值;控制条件;迭代){ 循环体; } 3 while和do-while什么区别 while先判断后执行dowhile是先执行再判断(先斩后奏) 4 手写代码,写出使用for循环输出1-10的…

区块链笔记(五)---德勤相关分析报告

web3.0 定义&#xff1a; 在《Insights into a Modern World》提出&#xff0c;“信息将由用户自己发布、保管、不可追溯且永远不会泄露&#xff0c;用户的任何行为将不需要任何中间机构来帮助传递”&#xff1b;用来指代一种区块链技术&#xff0c;可以基于“无须信任的交互…

微信小程序开发:通过wx.login()获取用户唯一标识openid和unionid

下面代码展示了 openid 的获取过程。 想获取 unionid 需要满足条件&#xff1a;小程序已绑定到微信开放平台账号下&#xff0c;不然只会返回 openid。 【相关文档】 微信小程序开发&#xff1a;appid 和 secret 的获取方法 wx.login({success (res) {if (res.code) {// 发起网…

【机器学习的基本术语和概念】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 简述概要知识图谱 简述概要 提示&#xff1a;简要描述文章内容&#xff0c;适合哪些人观看 知识图谱 样本&#xff08;Sample&#xff09;/实例&#xff08;Instance&#xff09;&#xff1a;在机器学习中&#xff0c;我…

Linux中的各类时间 与 find命令的常用参数

之前研究wal日志清理的副产物&#xff0c;wal日志名被修改后文件的哪个时间会变&#xff1f;应该如何删除&#xff1f;由此整理一下Linux中atime、mtime、ctime的区别&#xff0c;以及find的常见用法。 一、 Linux中的各类时间 1. 各类时间的定义 Linux中有三种用于文件时间戳…

你听说过柔性数组吗?

目录 1. 柔性数组的概念 2. 柔性数组的特点 3. 柔性数组的使用 4. 柔性数组的优势 5.完结散花 悟已往之不谏&#xff0c;知来者犹可追 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#…

个人博客系列-项目部署-nginx(3)

使用Nginx uwsgi进行部署django项目 一. 检查项目是否可以运行 启动项目 python manage.py runserver 0.0.0.0:8099输入ip:8099 查看启动页面 出现上述页面表示运行成功 二. 安装uwsgi并配置 2.1 下载uwsgi pip install uwsgi新建文件test.py写入内容&#xff0c;测试一…

【操作系统】磁盘文件管理系统

实验六 磁盘文件管理的模拟实现 实验目的 文件系统是操作系统中用来存储和管理信息的机构&#xff0c;具有按名存取的功能&#xff0c;不仅能方便用户对信息的使用&#xff0c;也有效提高了信息的安全性。本实验模拟文件系统的目录结构&#xff0c;并在此基础上实现文件的各种…

【前端素材】推荐优质后台管理系统Spica Admin平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

会话技术之cookie和session

COOKIE 什么是COOKIE? Cookie是由网站存储在用户计算机上的小型文本文件&#xff0c;用于在用户访问网站时跟踪和识别用户。Cookie可以在用户的计算机上存储有关用户行为和偏好的信息&#xff0c;以便在用户下次访问相同网站时提供个性化的体验。以下是一些关于Cookie的重要…

C语言——指针——第2篇——(第20篇)

坚持就是胜利 文章目录 一、指针和数组二、二级指针1、什么是 二级指针&#xff1f;2、二级指针 解引用 三、指针数组模拟二维数组 一、指针和数组 问&#xff08;1&#xff09;&#xff1a;指针和数组之间是什么关系呢&#xff1f; 答&#xff1a;指针变量就是指针变量&…

【Linux】一站式教会:Ubuntu(无UI界面)使用apache-jmeter进行压测

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Java…

C++:string类

标准库中的string类 string类 1. 字符串是表示字符序列的类 2. 标准的字符串类提供了对此类对象的支持&#xff0c;其接口类似于标准字符容器的接口&#xff0c;但添加了专门用于操作单字节字符字符串的设计特性。 3. string类是使用char(即作为它的字符类型&#xff0c;使用…
最新文章