数据结构--循环队列的c语言实现(超详细注释/实验报告)

2023-11-07

数据结构–循环队列的c语言实现(超详细注释/实验报告)

知识小回顾

队列(Queue)是另一种限定性的线性表,它只允许再表的一端插入元素,而再另一端删除元素,多以队列具有先进先出(First In First Out,FIFO)的特性。这与我们日常生活中的排队是一样的,最早进入队列的人最早离开,新来的人总是加入到队尾。在队列中,允许插入的一端称为队尾(Rear),允许删除的一端则称为队头(Front)。

队列在程序设计中也经常出现。一个最典型的例子就是操作系统中的作业排队。在允许多道程序运行的计算机系统中,同时有几个作业在运行。如果运行的结果都需要通过通道输出,那么就要按请求输出的先后次序排队。凡是申请输出的作业都从队尾进入队列。

循环队列是队列的一种顺序表示和实现方法。与顺序栈类似,在队列的顺序存储结构中,用一组地址连续的存储单元依次存放从队头到队尾的元素。此外,由于队列中队头和队尾的位置都是动态变化的,因此需要附设两个指针front和rear,分别知识队头元素和队尾元素在数组中的位置。

普通的顺序队列会有假溢出,一个巧妙的办法就是将顺序队列的数组看成一个环状的空间,即规定最后一个单元的后继为第一个单元,我们形象地称之为循环队列。

实验题目

实现循环队列基本运算

实验目的

  1. 掌握队列的逻辑结构和操作规则,能在相应的实际问题中正确选用。
  2. 熟练掌握循环队列基本运算的实现

实验要求

  1. 以循环队列作为存储结构;
  2. 实现循环队列的建立;
  3. 实现循环队列的入队运算;
  4. 实现循环队列的出队运算。

实验内容和实验步骤

1.需求分析

 以菜单的形式作为用户与程序的接口,用户输入菜单号来实行相应的操作。

2. 概要设计

 设计几个函数来实现初始化、插入、删除和查找的功能,然后再主函数中调用函数来实现操作。

3. 详细设计

导入一些库,并定义队列的大小以及队列中元素的类型。

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define MAXSIZE 50//队列最大长度
循环队列类型定义如下
typedef int QueueElementType;
typedef struct
{
    QueueElementType element[MAXSIZE];//队列的元素空间(一个数组)
    int front;//头指针(指示器)
    int rear;//尾指针(指示器)
}SeqQueue;

循环队列初始化操作
//循环队列初始化操作
SeqQueue*InitQueue()
{
    //将Q初始化为一个空的循环队列
    SeqQueue *Q;
    Q=(SeqQueue*)malloc(sizeof(SeqQueue));
    Q->front=Q->rear=0;//一开始两个指示器都在最前面
    return Q;
}
循环队列入队操作
  • 在非空循环队列中,队头指针始终指向当前队头元素,而队尾指针始终指向真正队尾与那苏后面的单元。当队列空间被占满时,队尾指针追上队头指针,所以有:front=rear。反之,队列是空的时候,队头指针追上队尾指针,此时也有:front=rear。可见,只凭front=rear无法判断队列是“满”还是“空”。解决这个问题的办法就是:损失一个元素,当队尾指针所指向的空单元的后继单元是队头元素所在的单元时,则停止入队。
//循环队列入队操作
void EnterQueue(SeqQueue *Q,QueueElementType x)
{
    //printf("入队开始\n");
    if((Q->rear+1)%MAXSIZE==Q->front)//牺牲了一个空间
    {
        printf("循环队列已满");
    }
    else
    {
        //printf("入队else开始\n");
        Q->element[Q->rear]=x;
        Q->rear=(Q->rear+1)%MAXSIZE;
    }
    //printf("入队结束\n");
}
循环队列出队操作
//循环队列出队操作
void DeleteQueue(SeqQueue *Q)
{
    if(Q->front==Q->rear)
    {
        printf("队列为空");
    }
    else
    {
        Q->front=(Q->front+1)%MAXSIZE;
    }
}
循环队列显示操作
//循环队列显示操作
void DisplayQueue(SeqQueue *Q)
{
    //printf("display开始\n");
    int i;
    for(i=Q->front;i!=Q->rear;i=(i+1)%MAXSIZE)
    {
        printf("%d   ",Q->element[i]);
    }
    //printf("display结束\n");
}

主函数部分,用一种“菜单”的形式使线性表的操作更加地清晰地展示出来。
在这里插入图片描述

//主函数
int main()
{
    SeqQueue *Q;
    //InitQueue(Q);
    Q=InitQueue();
    int a,i=1,x;
    for(a=1;a<5;a++)
    {
        EnterQueue(Q,a);
    }
    //DisplayQueue(Q);
    system("cls");
    while(i)//保证一直进行
    {
        printf("当前的循环队列如下(队首->队尾):\n");
        DisplayQueue(Q);
        printf("\n------------------------------------\n");
        printf("         Main Menu         \n");
        printf("    1   进队    \n");
        printf("    2   出队   \n");
        printf("    3   清屏   \n");
        printf("    0   结束程序   \n");
        printf("------------------------------------\n");
        printf("请输入你选择的菜单号<1, 2, 3, 0>:\n");
        scanf("%d",&i);
        switch(i)
        {
        case 1:
            printf("请输入进队元素:");
            scanf("%d",&x);
            EnterQueue(Q,x);
            printf("\n\n");
            break;
        case 2:
            DeleteQueue(Q);
            printf("\n\n");
            break;
        case 3:
            system("cls");
            break;
        case 0:
            exit(0);
            break;
        default:
            printf("输入有误~\n");
            break;
        }
    }
}

4. 调试分析

遇到的问题及解决方法
  • 教材上的初始化操作报错,用来实验指导书上的代码后就没有报错了。
算法的时空分析
  • 循环链表比较简单,都是依托着数组来实现的,所以整体难度不大,最多也就一层循环
实验结果

实验结果很不错,所有操作都能正常执行,并且自己加入了“清屏”选项,使得界面更加的整洁。

实验总结

循环链表比较简单,多多重复,百炼成钢!

最后附上完整的代码

#include<stdio.h>
#include<stdlib.h>
//#include<malloc.h>
#define MAXSIZE 50//队列最大长度
typedef int QueueElementType;
typedef struct
{
    QueueElementType element[MAXSIZE];//队列的元素空间(一个数组)
    int front;//头指针(指示器)
    int rear;//尾指针(指示器)
}SeqQueue;

//循环队列初始化操作
//void InitQueue(SeqQueue * Q)
SeqQueue*InitQueue()
{
    //将Q初始化为一个空的循环队列
    SeqQueue *Q;
    Q=(SeqQueue*)malloc(sizeof(SeqQueue));
    Q->front=Q->rear=0;//一开始两个指示器都在最前面
    return Q;
}

//循环队列入队操作
void EnterQueue(SeqQueue *Q,QueueElementType x)
{
    //printf("入队开始\n");
    if((Q->rear+1)%MAXSIZE==Q->front)//牺牲了一个空间
    {
        printf("循环队列已满");
    }
    else
    {
        //printf("入队else开始\n");
        Q->element[Q->rear]=x;
        Q->rear=(Q->rear+1)%MAXSIZE;
    }
    //printf("入队结束\n");
}

//循环队列出队操作
void DeleteQueue(SeqQueue *Q)
{
    if(Q->front==Q->rear)
    {
        printf("队列为空");
    }
    else
    {
        Q->front=(Q->front+1)%MAXSIZE;
    }
}

//循环队列显示操作
void DisplayQueue(SeqQueue *Q)
{
    //printf("display开始\n");
    int i;
    for(i=Q->front;i!=Q->rear;i=(i+1)%MAXSIZE)
    {
        printf("%d   ",Q->element[i]);
    }
    //printf("display结束\n");
}

//主函数
int main()
{
    SeqQueue *Q;
    //InitQueue(Q);
    Q=InitQueue();
    int a,i=1,x;
    for(a=1;a<5;a++)
    {
        EnterQueue(Q,a);
    }
    //DisplayQueue(Q);
    system("cls");
    while(i)//保证一直进行
    {
        printf("当前的循环队列如下(队首->队尾):\n");
        DisplayQueue(Q);
        printf("\n------------------------------------\n");
        printf("         Main Menu         \n");
        printf("    1   进队    \n");
        printf("    2   出队   \n");
        printf("    3   清屏   \n");
        printf("    0   结束程序   \n");
        printf("------------------------------------\n");
        printf("请输入你选择的菜单号<1, 2, 3, 0>:\n");
        scanf("%d",&i);
        switch(i)
        {
        case 1:
            printf("请输入进队元素:");
            scanf("%d",&x);
            EnterQueue(Q,x);
            printf("\n\n");
            break;
        case 2:
            DeleteQueue(Q);
            printf("\n\n");
            break;
        case 3:
            system("cls");
            break;
        case 0:
            exit(0);
            break;
        default:
            printf("输入有误~\n");
            break;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构--循环队列的c语言实现(超详细注释/实验报告) 的相关文章

  • css强制换行和禁止换行

    强制换行 word break break all 只对英文起作用 以字母作为换行依据 word wrap break word 只对英文起作用 以单词作为换行依据 white space pre wrap 只对中文起作用 强制换行 禁止换
  • SpringBoot注解+AOP实现

    SpringBoot注解 AOP实现 Java Annotation注解的详解 Java注解是一种元数据 它可以用于在类 方法或其他代码结构中声明关于程序元素的信息和标记 在Java中 注解以 符号开头 在编译时或运行时由Java虚拟机 J
  • TEA、XTEA、XXTEA加密解密算法

    参考 TEA XTEA XXTEA加密解密算法 地址 https blog csdn net gsls200808 article details 48243019 其他相关博文链接 tea系列加密算法学习笔记 TEA和XxTEA跨平台加密
  • 【其他】资源整合

    偶然整理云盘 发现曾经收藏过一些比较不错的资源 正好分享一下 1 C语言教程 郝斌老师作为读书时候的启蒙老师 推荐一波 链接 https pan baidu com s 10NIZ3x4yPP4YP8bYmVENHg 密码 6jj1 2 U
  • Node的Buffer对象和fs模块

    一 Node的模块化管理 1 模块化 node应用程序由模块组成 遵循的是CommonJS模块规范 使用模块管理的好处是隔离模块的作用域 避免出现命名冲突 2 什么是CommonJS 是一套代码的规范 构建一个在浏览器之外的JavaScri

随机推荐

  • C/C++编程:仿函数

    概述 仿函数 也叫做函数对象 就实现意义而言 函数对象 比较贴切 一种具有函数特性的对象 就行为而言 仿函数 更贴切 这种东西可以像函数一样被调用 被调用者则以对象所定义的function call operator扮演函数的实质角色 仿函
  • &2 应用层 - 应用层协议原理

    应用层协议原理 一 网络应用程序体系结构 客户机 服务器 体系结构 纯P2P 体系结构 客户机 服务器与P2P的混合 二 进程通信 客户机和服务器进程 套接字 socket 进程与套接字关系 进程寻址 进程识别信息 两部分 用户代理 use
  • C++中的vector容器 模板类有两个参数

    std vector lt Eigen Matrix3d Eigen aligned allocatorEigen Matrix3d gt vector的声明如下 template
  • 记录用户上次看视频的进度,并且从记录的时间继续观看

    思路 因为视频多个 所以定义一个数组接收该用户已观看但是未观看完毕的字段 videoPlanArr 第一次进入获取本地储存的字段 videoPlanArr 如果没有获取到的话储存该视频id 有的话查询是否在数组中 未找到就把视频id添加进v
  • 数据库分库分表实战

    一 使用场景 当单个数据库实例达到瓶颈 例如连接数过多 处理能力受限 存储容量不足 磁盘IO达到瓶颈 内存不足 都需要对数据库进行分库分表 二 垂直切分 数据库表按列拆分 拆分后 数据库从一个数据列多的表变成了多个数据列少的表 数据垂直切分
  • win10系统 总是显示执行此操作需要Internet

    最近在重新设置电脑登录方式时 系统总是显示 执行此操作需要Internet 解决方法如下 首先右键开始图标 以管理员身份打开PowerShell 然后输入 netsh winsock reset 进行重置 winsock是Windows网络
  • 关于对数据结构的理解

    数据结构是计算机存储 组织数据的方式 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合 数据结构反映数据的内部构成 即数据由那部分构成 以什么方式构成 以及数据元素之间呈现的结构 数据结构就是研究数据的逻辑结构和物理结构以及它们之
  • 数据库总结(七)

    数据库设计 7 1 数据库设计概述 1 数据库设计 数据库设计是指对于一个给定的应用环境 构造 设计 优化的数据库逻辑模式和物理结构 并据此建立数据库及其应用系统 使之能够有效地存储和管理数据 满足各种用户的应用需求 包括信息管理要求和数据
  • Spring AOP 剖析(6)

    Spring AOP 的底层实现机制 2 Spring AOP 中的 Pointcut 6 扩展 Pointcut 如何前面的 Pointcut 类型都无法满足要求 这种情况下可以扩展 Spring AOP 的 Pointcut 给出自定义
  • web复习之从头到尾看看(1)

    主要是一些我认为自己没有掌握的细节性问题 仅供参考 欢迎大家一起学习 留言 你认为最有可能考的内容 换行标签 lt gt 内加br br span 不能包含 div 与 p 超链接 a href 链接内容 target 在何处打开 self
  • Python绘制三角函数图像

    可以使用Python的matplotlib库来绘制三角函数图像 首先 定义一个x值的范围 然后使用matplotlib的plot 函数绘制三角函数 最后使用matplotlib的show 函数显示图像
  • HTML 取消input自动提示

    input 输入框有提示功能 当你之前输入过一些内容 你下次打入相关字符的时候 默认会有之前输入的一些相关的字符的提示 这个提示一般来说还是很好的 但是 有时候 我们想自己输入 不想要提示 如果不需要提示 则将 autocomplete设置
  • ubuntu的终端命令提示符太长的修改方法总结

    2019独角兽企业重金招聘Python工程师标准 gt gt gt ubuntu的终端命令提示符太长 主要原因 1 计算机名太长 2 多层直接显示出来 针对计算机名太长的处理 如 下面的计算机名提示太长了 ningcaichen virtu
  • Java的byte类型详解

    前言 byte这个单词是Java八种基本数据类型之一字节的关键字 在计算机存储中以字节为单位 8位比特 bit 组成一个字节 为什么弄清楚byte这么重要呢 因为智能硬件的数据传输大部分协议都是按字节一位一位来解析的 对于字节的运算十分频繁
  • 备战蓝桥杯-二分查找(附多道题解和详细分析)

    二分典型例题 备战蓝桥杯系列全部文章 分享看过的高赞的文章 有助于你对于二分的理解 巨人的肩膀 知乎 二分的解释 LeetCode二分的解释 给定一个按照升序排列的长度为 nn 的整数数组 以及 qq 个查询 对于每个查询 返回一个元素 k
  • 直播邀约|8个数字了解2023腾讯全球数字生态大会

    2023腾讯数字生态大会 一起来看看吧
  • ❤ npm install 时报Error: spawn git ENOENT

    npm install 时报Error spawn git ENOENT 原因 主要是因为由于 git 的环境变量未设置导致 所以安装一下git 的环境变量就O了 步骤如下 设置 gt gt 系统 gt gt 高级系统设置 gt gt 高级
  • linux系统下修改文件夹目录权限

    文件夹权限问题 Linux Fedora Ubuntu修改文件 文件夹权限的方法差不多 很多人开始接触Linux时都很头痛Linux的文件权限问题 这里告诉大家如何修改Linux文件 文件夹权限 以主文件夹下的一个名为cc的文件夹为例 下面
  • nodejs第五天 npm yarn pnpm 包管理器

    文章目录 npm package json 安装包 全局安装 配置镜像 yarn 安装使用 镜像配置 pnpm 使用 镜像 npm node中的包管理器叫做npm node package manage 我们可以将自己开发的包上传到npm中
  • 数据结构--循环队列的c语言实现(超详细注释/实验报告)

    数据结构 循环队列的c语言实现 超详细注释 实验报告 知识小回顾 队列 Queue 是另一种限定性的线性表 它只允许再表的一端插入元素 而再另一端删除元素 多以队列具有先进先出 First In First Out FIFO 的特性 这与我