循环队列–C语言实现–数据结构「建议收藏」

循环队列–C语言实现–数据结构「建议收藏」循环队列–C语言实现–数据结构目录循环队列C语言实现数据结构目录一要求二循环队列三循环队列的算法设计1建立循环队列2置空队列3入队4出队5打印队四程序1程序的结构2程序源码五程序测试1入队列2出队列3打印队列六源程序及封装软件下载下载地址格格是一枚智能专业的本科在校生很愿意和各位大佬交流如果大家有愿意交朋友的可以加格格的QQ4460

大家好,又见面了,我是你们的朋友全栈君。

循环队列–C语言实现–数据结构


目录


(一) 要求

假设以数组sequ[m]存放循环队列的元素,同时设变量rear和quelen 分别指示循环队列中队尾元素的位置和内含元素的个数。编写实现该循环队列的入队和出队操作的算法。提示:队空的条件:sq->quelen==0;队满的条件:sq->quelen==m。


(二) 循环队列

定义:为充分利用向量空间,克服”假溢出”现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现, 当然也可以利用顺序表来实现。顺序表就是我们熟悉的数组 eg. sun[]
回顾:我们再来回顾一下关于顺序队列的重要知识点。队列通常与栈对应,栈是一种后进先出的单端(尾端)处理的数据结构;那么与之对应的队列是一种先进先出的双端(头尾两端)的数据结构。队列的特点就是在一段进行入队(存储数据)操作,在另一端进行出队(删除数据)操作。
为什么设计循环队列:大家在处理队列的时候,会遇到如下情况。例如说:我们的队列空间能够容纳1000个元素。首先,格格入队1000个元素,队列上溢,此时为“真溢出”。那么现在我们进行出队操作,我们一直出队,一直出队, 知道1000个元素全部被删除,此时我们发现队列仍然处于“上溢”状态,why? 其实原因很简单,在非循环队列当中,无论我们的front指(偏移)到哪里,只要我们的rear指(偏移)向上阙,那么队列就是“满溢”的。这就造成了空间明明还被占据着,但是队列却已经无用武之地的窘境。对于空间有限的计算机来说,这无疑是一种浪费。也不是一个优秀的程序猿想要看到的。所以在这种情况下,循环队列诞生了。循环队列当中的“满溢”只有一种情况,那就是所有数据空降都被占领了。而不会存在非循环队列当中的“假溢出”现象。


我们所常见的顺序循环队列通常有两种数据结构。

结构一

typedef struct
{
    datatype sequ[m];
    //sequ[]为我们所建立的顺序表(sequence)
    int  front,rear;
    //front表示队列头的偏移量,rear表示队列的尾的偏移量
}qu;//qu是队列(queue)的缩写

这里写图片描述

结构二

typedef struct
{
    datatype sequ[m];
    //sequ[]为我们所建立的顺序表(sequence)
    int  rear, quelen;
    //rear表示队列的尾的偏移量,quelen表示的是队列中元素的个数
}qu;//qu是队列(queue)的缩写

那通过观察这两种机构我们能够很容易的发现,数据结构并不是固定的。我们觉得那种算法比较更合理,我们觉得哪种数据结构方便我们设计算法,那么我们就建立哪种数据结构。在本文当中,我们采用第二种数据结构。显而易见的是,当我们采用第二种数据结构时,我们建立的一个队列指针(qu*sq)队空的条件:sq->quelen==0;队满的条件:sq->quelen==m。


(三) 循环队列的算法设计


在上面我们了解了循环队列的数据机构,但是仅仅学会了数据结构还远远不够。我们设计数据结构的目的是为了更好的存储数据,并利用数据。下面我们来看一看关于循环队列我们要掌握哪些最基本的算法(利用数据机构)。


3.1 建立循环队列

//建立队
qu* creatqueue();//函数声明
qu* creatqueue()//函数实现
{
    qu *sq;
    sq=(qu*)malloc(sizeof(qu));
    return sq;  
}

3.2 置空队列

//置空队
void setnull(qu*);//函数声明
void setnull(qu *sq)//函数实现
{
    sq->rear = m - 1;
    sq->quelen = 0;
}

3.3 入队

//入队
void enqueue(qu*, datatype);//函数声明
void enqueue(qu*sq, datatype x)//函数实现
{
    if (sq->quelen == 5)
        printf("Errot! The queue will be overflow! \n");
    else if((sq->rear+1)==m)
    {
        sq->rear = (sq->rear + 1) % m;
        sq->sequ[sq->rear] = x;
        sq->quelen++;
        printf("过5入队成功!\n");
    }
    else
    {
        sq->rear++;
        sq->sequ[sq->rear] = x;
        sq->quelen++;
        printf("入队成功!\n");
    }
}

**算法流程图**


3.4 出队

//出队
datatype *dequeue(qu*);//函数声明
datatype *dequeue(qu*sq)//函数实现
{
    datatype sun=0;
    if (sq->quelen == 0)
    {
        printf("Error! The queue will be under flow!\n");
        return 0;
    }
    else if ((sq->rear + 1) >= sq->quelen)
    {
        sq->quelen--;
        sun = sq->sequ[sq->rear - sq->quelen];
        return(&sun);
    }
    else    //  if(sq->rear < sq->quelen)
    {
        sq->quelen--;
        sun = sq->sequ[sq->rear - sq->quelen + m];
        return(&sun);
    }
}

**算法流程图**


3.5 打印队

//打印队
void print(qu*);//函数声明
void print(qu*sq)//函数定义
{
    if (sq->quelen == 0)
        printf("Error! The queue is Null!\n");
    else if ((sq->rear + 1) >= sq->quelen)
    {
        int i = sq->rear + 1 - sq->quelen;
        for (i; i <= sq->rear; i++)
            printf("%d ", sq->sequ[i]);
    }
    else
    {
        int t = sq->rear - sq->quelen + m +1;
        int time = 1;
        for (t; time <= (sq->quelen); time++)
        {
            printf("%d ", sq->sequ[t]);
            t++;
            if (t == m)
            {
                t = 0;
                continue;
            }
            else
            {
                continue;
            }
        }
    }
    printf("\n");
}

(四) 程序


下面我们来设计一个程序测试我们的数据机构与算法


4.1 程序的结构

**程序结构**


4.2 程序源码

注意:该程序由Microsoft Visual Studio Enterprise 2015编译器进行调试。受制于编译器品牌及版本不同等不可抗因素造成的编译失败,请自行调整。

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define m 5

//循环队列的结构类型定义
typedef int datatype;
typedef struct
{
    datatype sequ[m];
    int  rear, quelen;
}qu;

//函数声明
qu* creatqueue();
void setnull(qu*);
void enqueue(qu*, datatype);
datatype *dequeue(qu*);
void print(qu*);

//主函数
void main()
{
    qu *sq= creatqueue();

    datatype x, *p;
    int key;

    setnull(sq);
    do
    {
        printf("1.Enter Queue 2.Delete Queue 3.clc display 4.print queue -1.Quit:");
        scanf_s("%d", &key);
        switch (key)
        {
        case 1:  printf("Enter the Data:"); scanf_s("%d", &x);
            enqueue(sq, x);  break;
        case 2:  p = dequeue(sq);
            if (p != NULL) printf("%d\n", *p);
            break;
        case 3:system("cls"); break;
        case 4:print(sq); break;
        case -1: exit(0);
        }
    } while (1);
}

//建立队
qu* creatqueue()
{
    qu *sq;
    sq=(qu*)malloc(sizeof(qu));
    return sq;  
}
//置空队
void setnull(qu *sq)
{
    sq->rear = m - 1;
    sq->quelen = 0;
}

//入队
void enqueue(qu*sq, datatype x)
{
    if (sq->quelen == 5)
        printf("Errot! The queue will be overflow! \n");
    else if((sq->rear+1)==m)
    {
        sq->rear = (sq->rear + 1) % m;
        sq->sequ[sq->rear] = x;
        sq->quelen++;
        printf("过5入队成功!\n");
    }
    else
    {
        sq->rear++;
        sq->sequ[sq->rear] = x;
        sq->quelen++;
        printf("入队成功!\n");
    }
}


//出队
datatype *dequeue(qu*sq)
{
    datatype sun=0;
    if (sq->quelen == 0)
    {
        printf("Error! The queue will be under flow!\n");
        return 0;
    }
    else if ((sq->rear + 1) >= sq->quelen)
    {
        sq->quelen--;
        sun = sq->sequ[sq->rear - sq->quelen];
        return(&sun);
    }
    else    // if(sq->rear < sq->quelen)
    {
        sq->quelen--;
        sun = sq->sequ[sq->rear - sq->quelen + m];
        return(&sun);
    }
}

//打印队列
void print(qu*sq)
{
    if (sq->quelen == 0)
        printf("Error! The queue is Null!\n");
    else if ((sq->rear + 1) >= sq->quelen)
    {
        int i = sq->rear + 1 - sq->quelen;
        for (i; i <= sq->rear; i++)
            printf("%d ", sq->sequ[i]);
    }
    else
    {
        int t = sq->rear - sq->quelen + m +1;
        int time = 1;
        for (t; time <= (sq->quelen); time++)
        {
            printf("%d ", sq->sequ[t]);
            t++;
            if (t == m)
            {
                t = 0;
                continue;
            }
            else
            {
                continue;
            }
        }
    }
    printf("\n");
}


(五) 程序测试


5.1 入队列

**入队列及上溢检测**


5.2 出队列

出队列及下溢检测


5.3 打印队列

前面已经用到了打印队列,所以格格不再赘述,大家由5.2&5.3可知打印队列是成功的。


(六) 源程序及封装软件下载

下载地址


格格是一枚智能专业的本科在校生,很愿意和各位大佬交流。如果大家有愿意交朋友的,可以加格格的QQ:446019725,声明是CSDN即可。



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137238.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月2日 下午12:00
下一篇 2022年6月2日 下午12:16


相关推荐

  • 在python中,如果异常并未被处理或捕捉_抛出异常是什么意思

    在python中,如果异常并未被处理或捕捉_抛出异常是什么意思一文掌握Pyhton的异常捕获和抛出,包括Python内置异常类型、自定义异常类等。

    2022年10月17日
    5
  • CICD介绍「建议收藏」

    CICD介绍「建议收藏」CICD一概要CICD的采用改变了开发人员和测试人员如何发布软件最初是瀑布模型,后来是敏捷开发,现在是DevOps,这是现代开发人员构建出色的产品的技术路线。随着DevOps的兴起,出现了持续集成(ContinuousIntegration)、持续交付(ContinuousDelivery)、持续部署(ContinuousDeployment)的新方法。传统的软件开发和…

    2022年5月16日
    49
  • Lombok插件讲解

    Lombok插件讲解Lombok 是什么 lombok 是 java 自动生成代码的插件 它能提高开发效率 减少自己编写繁琐的代码 让代码看起来更整洁简略 比如 getter setter equals 以及 construct 等方法 其也有 val var 这种自动判断变量类型的变量定义方式 类似 javascript 中的 let const Lombok 使用在开发 ide 中安装 lombok 插件 然后加上 lombok 的依赖包

    2026年3月18日
    2
  • Springboot单元测试_怎么启动汽车步骤

    Springboot单元测试_怎么启动汽车步骤图文带你debug源码分析SpringApplication准备阶段1、配置文件的加载时机?2、日志系统初始化时机?3、SpringBootprepareContext()源码解析4、SpringBootprepareEnvironment()源码解析

    2025年10月12日
    4
  • TerminateThread函数学习

    TerminateThread函数学习终结一个线程 BOOLWINAPITe Inout nbsp nbsp HANDLEhThrea In nbsp nbsp nbsp nbsp nbsp DWORDdwExitC ParametershT nbsp in out 要终结线程的句柄 这个句柄必须有 THREAD TERMINATE 权利 dwExitCode nbsp in 线程的退出值

    2026年3月19日
    2
  • Springboot自动装配的原理「建议收藏」

    Springboot自动装配的原理「建议收藏」springboot在日常开发中减少了我们许多工作量减少了很多XML配置,这都得益于springboot自动装配的特性。那么springboot是如何实现自动装配的呢?首先我们浅显得介绍一些springboot的一些主要注解:@Configuration用于声明定义bean这也是springboot中的主要注解其实就是平常Spring配置文件中我们写的bean@EnableAutoConfiguration用来开启springboot自动配置的注解,这个也是自动装…

    2022年8月20日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号