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

news2024/12/24 21:58:31

目录

一、顺序队列

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;
}

  五、运行结果

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

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

相关文章

[docker] Docker 网络

一、Docker 网络 1.1 Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认…

【嵌入式学习】网络通信基础-项目篇:简单UDP聊天室

源码已在GitHub开源&#xff1a;0clock/LearnEmbed-projects/chat 实现的功能 客户端功能&#xff1a; 上线发送登录的用户名[yes] 发送消息和接收消息[yes] quit退出 服务器端功能&#xff1a; 统计用户上线信息&#xff0c;放入链表中[yes] 接收用户信息并给其他用户发送消…

基于springboot+vue的在线商城系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

“探索C语言操作符的神秘世界:从入门到精通的全方位解析“

各位少年&#xff0c;我是博主那一脸阳光&#xff0c;今天来分享深度解析C语言操作符&#xff0c;C语言操作符能帮我们解决很多逻辑性的问题&#xff0c;减少很多代码量&#xff0c;就好比数学的各种符号&#xff0c;我们现在深度解剖一下他们。 前言 在追求爱情的道路上&…

Conda python管理packages二 从入门到精通

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装Conda python运行的包和环境管理 入门Conda python管理环境environments 一 从入门到精通Conda python管理环境environments 二 从入门到精通Conda python管理环境environments 三 从入门到精通…

华为服务器RAID5

0、BIOS默认密码 TaiShan 100服务器BIOS系统的默认密码为**“Huawei12#$”&#xff0c; TaiShan 200服务器BIOS系统的默认密码为“Admin9000”**。 1、服务器开机选择DEL,进行设置 2、选择设备管理器进入配置页面 3、选择AVAGO MegaRAID configuration utility 进入raid配置…

【软件测试】学习笔记-性能测试场景的分类

性能测试场景的重要程度类似于业务测试的 case&#xff0c;case 是你进行业务测试的指引&#xff0c;case 是否完善也直接决定了测试的覆盖率。同理&#xff0c;场景是传递执行性能测试的步骤和目的&#xff0c;关于这两点是你一定要清楚的。 首先认识下最重要的三个性能场景&…

C#从网址上读取json数据

需求&#xff1a;从客户给的网址中读取json格式的数据。 找了好多资料&#xff0c;都不太好使&#xff0c;看到了一篇很有帮助的文章。以下大部分内容和这篇找到的文章近似。太不容易了&#xff0c;同时也感谢这篇文章的作者心所欲。 https://www.cnblogs.com/zoujinhua/p/10…

Webpack5 基本使用 - 3(完结)

环境区分 可以定义多个配置文件&#xff0c;通过 webpack-merge 合并配置文件。 安装 webpack-merge yarn add webpack-merge公共配置 // webpack.common.js const path require(path) const HtmlWebpackPlugin require(html-webpack-plugin)module.exports {entry: path…

C/C++ 跨文件共享全局变量

目录 效果 项目 代码 下载 为了实现跨文件共享全局变量&#xff0c;我们可以使用 extern 关键字。extern 关键字用于声明一个变量&#xff0c;该变量在其他地方已经定义。它告诉编译器这个变量在其他文件中已经定义了&#xff0c;不需要重新分配内存空间&#xff0c;只需要…

PyTorch深度学习实战(32)——DCGAN详解与实现

PyTorch深度学习实战&#xff08;32&#xff09;——DCGAN详解与实现 0. 前言1. 模型与数据集分析1.1 模型分析1.2 数据集介绍 2. 构建 DCGAN 生成人脸图像小结系列链接 0. 前言 DCGAN (Deep Convolutional Generative Adversarial Networks) 是基于生成对抗网络 (Convolution…

《向量数据库指南》——Milvus Cloud向量数据库的新认知

除了数字上的里程碑,2023 年业务模式的改变也带来了很多定性的认知。这些认知帮助我们深化了对向量这种数据类型的理解,也引导了我们思考向量数据库未来的发展方向。 大模型应用仍处于初期阶段:避免重蹈智能手机时代“手电筒应用”的覆辙 回顾移动互联网早期,许多开发者创…

黑马苍穹外卖学习Day12

文章目录 工作台需求分析 Apache POI介绍入门案例 导出运营数据Excel报表需求分析代码开发 工作台 需求分析 Apache POI 介绍 入门案例 package com.sky.test;import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.a…

ubuntu20根目录扩容

ubuntu根目录/ 或者 /home文件夹有时出现空间满了的情况&#xff0c;可以用gparted工具进行空间的重新分配。 首先&#xff0c;如果你是双系统&#xff0c;需要从windows系统下磁盘压缩分配一部分未使用的空间给ubuntu&#xff0c;注意压缩的空间要邻接ubuntu所在盘的位置。 …

【学网攻】 第(4)节 -- 交换机划分Vlan

文章目录 【学网攻】 第(1)节 -- 认识网络 【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口 前言 网络已经成为了我们生活中不可或缺的一部分&#xff0c;它连接了世界各地的人们&#xff0c;让信息和资源得以自由流动。随着互联网的发展&am…

【pytorch】pytorch学习笔记

&#xff08;实践&#xff09;p5&#xff1a;线性回归问题中损失函数为什么要使用均方误差&#xff1f; 均方误差&#xff1a;即误差的平方和的平均数。 p8&#xff1a;1.pytorch不是一个完备的语言库&#xff0c;而是一个对于数据的gpu加速库&#xff0c;所以其没有对string…

【Golang入门教程】如何使用Goland创建并运行项目

自然语言处理的发展 文章目录 自然语言处理的发展**前言**创建新项目编辑运行/调试配置编写并运行代码总结强烈推荐专栏集锦写在最后 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站: 人工…

新能源汽车智慧充电桩管理方案:环境监测与充电安全多维感知

随着新能源技术的不断发展&#xff0c;新能源充电桩作为电动汽车的重要基础设施&#xff0c;其管理和维护变得尤为重要。环境监测类传感器能够实时监测充电桩周围的环境参数&#xff0c;如温度、湿度等&#xff0c;为管理人员提供及时、准确的数据&#xff0c;以便做出相应的调…

HTML+CSS:炫酷登录切换

效果演示 实现了一个登录注册页面的切换效果&#xff0c;当用户点击登录或注册按钮时&#xff0c;会出现一个叠加层&#xff0c;其中包含一个表单&#xff0c;用户可以在表单中输入用户名和密码&#xff0c;然后点击提交按钮进行登录或注册。当用户点击返回按钮时&#xff0c;会…

第三篇【传奇开心果短博文系列】Python的OpenCV库技术点案例示例:物体检测与识别

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例短博文系列 短博文目录一、项目目标二、OpenCV物体检测与识别介绍三、分别示例代码四、扩展示例代码 系列短博文目录 Python的OpenCV库技术点案例示例短博文系列 短博文目录 一、项目目标 物体检测与识别…