【数据结构】 循环队列的基本操作 (C语言版)

目录

一、顺序队列

1、顺序队列的定义:

2、顺序队列的优缺点:

二、循环队列

1、循环队列的定义:

2、循环队列的优缺点:

三、循环队列的基本操作算法(C语言)   

1、宏定义

  2、创建结构体

3、循环队列的初始化 

4、循环队列的销毁

5、循环队列的清空

6、求循环队列的长度

7、循环队列的判空

8、求队头元素

9、循环队列入队

10、循环队列出队

11、遍历队列元素

四、循环队列的基本操作完整代码(C语言)

  五、运行结果


一、顺序队列

1、顺序队列的定义:

顺序队列是由一维数组实现的队列,其中队头元素的下标为0,队尾元素的下标为n-1(n为数组大小),队列的大小在创建时确定,且在队列的生命周期内保持不变。

2、顺序队列的优缺点:

顺序队列的优点:

  1. 空间利用率高:由于数组的大小在创建时确定,因此可以预先分配足够的空间,避免了频繁的内存申请和释放操作,提高了空间利用率。
  2. 存取速度快:由于队列元素在内存中连续存储,因此可以根据下标直接访问队头元素和队尾元素,存取速度快。

顺序队列的缺点:

  1. 不适合处理动态扩展的数据:顺序队列的空间大小在创建时确定,因此无法动态扩展,对于需要处理大规模数据的情况不太适用。
  2. 容易发生假溢出:由于顺序队列的队头和队尾元素不断向后移动,当队列满时,如果继续入队操作,会导致假溢出,即无法再进行入队操作。
  3. 无法充分利用内存的连续性优势:由于顺序队列是基于数组实现的,因此无法充分利用内存的连续性优势,因为队头和队尾元素可能分散在不同的内存位置。

二、循环队列

1、循环队列的定义:

循环队列是一种线性数据结构,它将队列的元素存储在一个连续的数组中,并通过使用循环指针来管理队列的插入和删除操作。循环队列的特点在于,当队列为空时,头尾指针指向同一位置;当队列满时,头尾指针也指向同一位置。 

2、循环队列的优缺点:

循环队列的优点:

  1. 空间利用率高:循环队列使用固定大小的数组来存储元素,无需动态分配内存,因此可以充分利用存储空间。
  2. 时间复杂度稳定:在循环队列中,插入和删除操作具有固定的时间复杂度,这使得循环队列在需要频繁进行插入和删除操作的场景中表现优异。
  3. 无需额外的空间:由于循环队列使用数组实现,因此无需额外的空间来存储元素,从而降低了空间复杂度。

循环队列的缺点:

  1. 队列大小固定:循环队列的大小是固定的,因此在处理大量数据时,可能需要预先分配大量存储空间。如果实际数据量超过预分配的空间,可能会导致数据丢失或程序崩溃。
  2. 判断队列是否为空或满的判断逻辑较复杂:在循环队列中,判断队列是否为空或满的判断逻辑相对复杂。需要同时考虑头尾指针的位置和当前队列的状态。如果处理不当,可能会导致误判或错过一些特殊情况。
  3. 插入和删除操作需要移动元素:虽然循环队列在插入和删除操作时具有固定的时间复杂度,但在实际操作中,仍然需要移动元素以保持队列的连续性和循环性。如果数据量大或者数据不均匀分布,可能会影响操作效率。

三、循环队列的基本操作算法(C语言)   

1、宏定义
#define OK 1
#define ERROR 0
#define OVERFLOW -1

#define MAXSIZE 100

typedef int QElemType;
typedef int Status;
  2、创建结构体
//创建结构体
typedef struct {
    QElemType *base;
    int front;
    int rear;
} SqQueue;
3、循环队列的初始化 
//初始化
Status InitQueue(SqQueue &Q) {
    //构造一个空队列
    Q.base = new QElemType[MAXSIZE];
    if (!Q.base) {
        exit(OVERFLOW);
    }
    Q.front = Q.rear = 0;
    return OK;
}
4、循环队列的销毁
//销毁队列
Status DestroyQueue(SqQueue &Q) {
    if (Q.base) {
        delete Q.base;
    }
    Q.base = NULL;
    Q.front = Q.rear = 0;
    return OK;
}
5、循环队列的清空
//清空队列
Status ClearQueue(SqQueue &Q) {
    Q.front = Q.rear = 0;
    return OK;
}
6、求循环队列的长度
//求长度
Status QueueLength(SqQueue Q) {
    return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;

}
7、循环队列的判空
Status QueueEmpty(SqQueue Q) {
    if (Q.front == Q.rear) {
        return true;
    } else {
        return false;
    }
}
8、求队头元素
//求队头元素
Status GetHead(SqQueue Q, QElemType &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.base[Q.front];
    return OK;
}
9、循环队列入队
//循环队列入队
Status EnQueue(SqQueue &Q, QElemType e) {
    if ((Q.rear + 1) % MAXSIZE == Q.front) return ERROR;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXSIZE;
    return OK;
}
10、循环队列出队
//循环队列出队
Status DeQueue(SqQueue &Q, QElemType &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXSIZE;
    return OK;
}
11、遍历队列元素
//遍历队列
void DisplayQueue(SqQueue Q) {
    int i = Q.front;
    printf("队列元素为: ");
    while (Q.front != Q.rear && (i + MAXSIZE) % MAXSIZE != Q.rear) {
        printf("%d ", Q.base[i]);
        i++;
    }
}
四、循环队列的基本操作完整代码(C语言)
#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define OVERFLOW -1

#define MAXSIZE 100

typedef int QElemType;
typedef int Status;

//创建结构体
typedef struct {
    QElemType *base;
    int front;
    int rear;
} SqQueue;

//初始化
Status InitQueue(SqQueue &Q) {
    //构造一个空队列
    Q.base = new QElemType[MAXSIZE];
    if (!Q.base) {
        exit(OVERFLOW);
    }
    Q.front = Q.rear = 0;
    return OK;
}

//销毁队列
Status DestroyQueue(SqQueue &Q) {
    if (Q.base) {
        delete Q.base;
    }
    Q.base = NULL;
    Q.front = Q.rear = 0;
    return OK;
}

//清空队列
Status ClearQueue(SqQueue &Q) {
    Q.front = Q.rear = 0;
    return OK;
}

//求长度
Status QueueLength(SqQueue Q) {
    return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;

}

//判空
Status QueueEmpty(SqQueue Q) {
    if (Q.front == Q.rear) {
        return true;
    } else {
        return false;
    }
}

//求队头元素
Status GetHead(SqQueue Q, QElemType &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.base[Q.front];
    return OK;
}

//循环队列入队
Status EnQueue(SqQueue &Q, QElemType e) {
    if ((Q.rear + 1) % MAXSIZE == Q.front) return ERROR;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXSIZE;
    return OK;
}

//循环队列出队
Status DeQueue(SqQueue &Q, QElemType &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXSIZE;
    return OK;
}

//遍历队列
void DisplayQueue(SqQueue Q) {
    int i = Q.front;
    printf("队列元素为: ");
    while (Q.front != Q.rear && (i + MAXSIZE) % MAXSIZE != Q.rear) {
        printf("%d ", Q.base[i]);
        i++;
    }
}

//功能菜单列表
void show_help() {
    printf("******* 功能菜单列表 *******\n");
    printf("1----入队------------------\n");
    printf("2----求循环队列长度----------\n");
    printf("3----出队------------------\n");
    printf("4----取队头元素-------------\n");
    printf("5----清空循环队列-----------\n");
    printf("6----销毁循环队列-----------\n");
    printf("7----判断循环队列是否为空-----\n");
    printf("8----批量插入元素------------\n");
    printf("9----显示队列元素------------\n");
    printf("10----退出------------------\n\n");
}

int main() {
    SqQueue sq;

    //初始化
    Status rInitStack = InitQueue(sq);
    if (rInitStack == OK) {
        printf("循环队列初始化成功!\n");
    } else {
        printf("循环队列初始化失败!\n");
    }


    while (1) {

        //功能菜单列表
        show_help();

        int flag;
        printf("请输入所需的功能编号:\n");
        scanf("%d", &flag);

        switch (flag) {
            case 1: {//入队
                Status EnQueueindex;
                printf("请输入插入元素(请在英文状态下输入例如:1): \n");
                scanf("%d", &EnQueueindex);
                Status rEnQueue = EnQueue(sq, EnQueueindex);
                if (rEnQueue == OK) {
                    printf("向循环队列入队%d成功!\n", EnQueueindex);
                } else {
                    printf("向循环队列入队失败!\n");
                }
            }
                break;
            case 2: {//求循环队列的长度
                int length = QueueLength(sq);
                printf("循环队列的长度为:%d。 \n\n", length);
            }
                break;
            case 3: {//出队
                Status DeQueueindex;
                Status rDeQueue = DeQueue(sq, DeQueueindex);
                if (rDeQueue == OK) {
                    printf("向循环队列出队%d成功!\n", DeQueueindex);
                } else {
                    printf("向循环队列出队失败!\n");
                }
            }
                break;
            case 4: {//求队头元素
                Status topData;
                Status rGetHead = GetHead(sq, topData);
                if (rGetHead == OK) {
                    printf("向循环队列获取队头元素:%d\n", topData);
                } else {
                    printf("向循环队列获取队头元素失败!\n");
                }
            }
                break;
            case 5: { //清空
                Status rClearStack = ClearQueue(sq);
                if (rClearStack == OK) {
                    printf("循环队列清空成功!\n");
                } else {
                    printf("循环队列清空失败!\n");
                }
            }
                break;
            case 6: {//销毁
                Status rDestroyStack = DestroyQueue(sq);
                if (rDestroyStack == OK) {
                    printf("循环队列销毁成功!\n");
                } else {
                    printf("循环队列销毁失败!\n");
                }
            }
                break;
            case 7: {///判空
                Status ClearStatus = QueueEmpty(sq);
                if (ClearStatus == true) {
                    printf("循环队列为空!\n\n");
                } else {
                    printf("循环队列不为空!\n\n");
                }
            }
                break;
            case 8: {//批量插入
                int on;
                printf("请输入想要插入的元素个数:\n");
                scanf("%d", &on);
                QElemType array[on];
                for (int i = 1; i <= on; i++) {
                    printf("向循环队列第%d个位置插入元素为:", i);
                    scanf("%d", &array[i]);
                }

                for (int i = 1; i <= on; i++) {
                    Status InsertStatus = EnQueue(sq, array[i]);
                    if (InsertStatus == OK) {
                        printf("向循环队列第%d个位置插入元素%d成功!\n", i, array[i]);
                    } else {
                        printf("向循环队列第%d个位置插入元素%d失败!\n", i, array[i]);
                    }
                }
            }
                break;
            case 9: {//输出链表元素
                DisplayQueue(sq);
                printf("\n");
            }
                break;
            case 10: {//退出程序
                return 0;
            }
                break;
            default: {
                printf("输入错误,无此功能,请检查输入:\n\n");
            }
        }
    }

    return 1;
}

  五、运行结果

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

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

相关文章

PPO学习

openai用tf实现的真的看不懂&#xff0c;大佬的世界… PPO的详细细节 1. 奖励模型和策略的价值头将 query 和 response 的连接作为输入 奖励模型和策略的价值头 不 仅仅查看响应。相反&#xff0c;它将 query 和 response 连接在一起&#xff0c;作为 query_response def ge…

如何群发邮件outlook?外贸邮件群发教程?

outlook怎么设置邮件群发&#xff1f;outlook邮箱群发邮件方法&#xff1f; 在日常生活中&#xff0c;我们经常需要给多个人发送相同的邮件。这时候&#xff0c;群发邮件就显得尤为重要。Outlook作为一款常用的办公软件&#xff0c;提供了强大的邮件群发功能。蜂邮EDM就教大家…

Linux 文件:IO接口详解及实操

一、C语言中的文件IO读写操作 在c语言文件中&#xff0c;创建、打开、读、写操作可以通过如下的代码进行&#xff1a; 1.1写文件 通过w指令对文件进行写入操作时&#xff0c;编译器会先将文件内容清空然后重新写入。 #include <stdio.h> #include <string.h> i…

前端上传大文件使用分片上传

前提:分片上传针对于一些大的文件、普通大小的文件使用element中的上传组件可以实现效果,例如几G的文件就会比较卡,所以这时候就需要用到分片上传~ 前端及后端分片上传笔记 效果:(上传进度展示) 效果:(上传成功的效果展示) 1、 新建一个上传组件 2、使用vue-simple-…

ATF(TF-A)安全通告TF-V11——恶意的SDEI SMC可能导致越界内存读取(CVE-2023-49100)

目录 一、ATF(TF-A)安全通告TFV-11 (CVE-2023-49100) 二、透过事务看本质SDEI是干啥的呢&#xff1f; 三、CVE-2023-49100 1、GICv2 systems 2、GICv3 systems 四、漏洞修复 一、ATF(TF-A)安全通告TFV-11 (CVE-2023-49100) Title 恶意的SDEI SMC可能导致越界内存读取&am…

java数据结构与算法刷题-----LeetCode667. 优美的排列 II

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 解题思路 题目要求我们返回一个数组长度为n的数组&#xff0c;必须含有1~n…

ZK高可用架构涉及常用功能整理

ZK高可用架构涉及常用功能整理 1. zk的高可用系统架构和相关组件1.1 Quorum机制1.2 ZAB协议 2. zk的核心参数2.1 常规配置2.2 特殊优化配置 3. zk常用命令3.1 常用基础命令3.2 常用运维命令 4. 事务性4.1 数据写流程4.2 数据读流程 5. 疑问和思考5.1 zk不擅长处理哪些场景&…

详解一次一密

目录 一. 介绍 二. 一次一密方案 三. 正确性分析 四. 证明一次一密方案是完美安全 五. 一次一密的应用 六. 小结 一. 介绍 一次一密&#xff0c;英语写做one time pad。 在1917年&#xff0c;Vernam提出了一个完美安全的加密方案&#xff0c;后世将其称之为一次一密。在…

Element中的el-input-number+SpringBoot+mysql

1、编写模板 <el-form ref"form" label-width"100px"><el-form-item label"商品id&#xff1a;"><el-input v-model"id" disabled></el-input></el-form-item><el-form-item label"商品名称&a…

选择国产压测工具应注意什么?

随着互联网和信息技术的飞速发展&#xff0c;压力测试成为了确保软件系统稳定性和性能的不可或缺的环节。在压测工具的选择上&#xff0c;近年来国产压测工具逐渐崭露头角&#xff0c;但在使用时仍需谨慎。本文将探讨在选择国产压测工具时需要注意的关键因素。 功能完备性&…

离线编译 onnxruntime-with-tensortRT

记录为centos7的4090开发机离线编译onnxruntime的过程&#xff0c;因为在离线的环境&#xff0c;所以踩了很多坑。 https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html 这里根据官网的推荐安装1.15 版本的onnx 因为离线环境&#xff0c;所以很…

中国大模型迎来“95后” 百度奖学金发掘百位“未来AI技术领袖”

在人工智能掀起的科技革命和产业变革浪潮下&#xff0c;大模型成为最受关注的研究领域。1月22日&#xff0c;第十一届百度奖学金颁奖典礼在北京举行&#xff0c;来自全球顶尖高校及科研机构的10位“未来AI技术领袖”脱颖而出&#xff0c;他们平均年龄仅27岁&#xff0c;其中8人…

关于Redis的最常见的十道面试题-分布式锁和布隆过滤器

面试题一&#xff1a;有序集合在日常工作中的使用场景有哪些&#xff1f; 有序集合在工作中的应用场景有很多&#xff0c;例如“ 排行榜&#xff1a;可以将用户的得分作为有序集合的分支&#xff0c;用户的ID作为成员&#xff0c;通过有序集合的排名功能可以得到用户的排名信…

OpenCV第 2 课 OpenCV 环境搭建

文章目录 第 2 课 OpenCV 环境搭建1.安装 Numpy2.从 Ubuntu 存储库安装 OpenCV3.验证 OpenCV 安装 第 2 课 OpenCV 环境搭建 1.安装 Numpy 每一张图像都有很多个像素点&#xff0c;这也导致了程序中会涉及大量的数组处理。Numpy 是一个 Python 的拓展库&#xff0c;它对多维数…

MySQL怎么根据当前时间获取连续十二个月统计数据

需求 在某些业务场景中&#xff0c;需要后台获取连续十二个月的统计数据&#xff0c;如下图&#xff1a; 解决方式 1、创建一张临时表&#xff0c;在表中插入序号数据 该表的最大数量决定统计返回的最大条数 CREATE TABLE sys_redundancy (id bigint(22) NOT NULL AUTO_I…

YOLOv7调用摄像头检测报错解决

yolov7detect.py文件调用本地摄像头&#xff0c;把source参数设为0 parser.add_argument(--source, typestr, default0, helpsource) # file/folder, 0 for webcam 报错&#xff1a;cv2.error: OpenCV(3.4.2) 一堆地址:The function is not implemented. Rebuild the library…

【数据分析】matplotlib、numpy、pandas速通

教程链接&#xff1a;【python教程】数据分析——numpy、pandas、matplotlib 资料&#xff1a;https://github.com/TheisTrue/DataAnalysis 1 matplotlib 官网链接&#xff1a;可查询各种图的使用及代码 对比常用统计图 1.1 折线图 &#xff08;1&#xff09;引入 from …

时间序列大模型:TimeGPT

论文&#xff1a;https://arxiv.org/pdf/2310.03589.pdf TimeGPT&#xff0c;这是第一个用于时间序列的基础模型&#xff0c;能够为训练期间未见过的多样化数据集生成准确的预测。 大规模时间序列模型通过利用当代深度学习进步的能力&#xff0c;使精确预测和减少不确定性成为…

力扣hot100 排序链表 归并排序 递归

Problem: 148. 排序链表 &#x1f469;‍&#x1f3eb; 参考 &#x1f496; 归并排序&#xff08;递归&#xff09; ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) /*** Definition for singly-linked list.* public class ListNode {*…

【Go学习】Ginkgo测试框架学习实践 + 问题记录 + 怎么解决(0)

1、ginkgo测试框架介绍&#xff1a;https://onsi.github.io/ginkgo/ 2、重点是学习实践 问题记录 怎么解决 3、送福利&#xff1a;国内好用的ChatGpt有很多&#xff0c;比如&#xff1a;天工、文心一言、讯飞星火、通义万相等 1. 安装 xxxmacdeMacBook-Pro-3  /Volumes/mac…