C语言实现循环队列

C语言实现循环队列详解循环队列的巧妙之处

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

顺序队列的假溢出

顺序队列假溢出

1️⃣:初始化空队列,q -> front = q -> rear = 0

2️⃣:入队a1、a2、a3,q -> front = 0, q -> rear = 3

3️⃣:出队a1、a2,q -> front = 2, q -> rear = 3

4️⃣:入队a4、a5、a6,q -> front = 2, q -> rear = 6

执行 4️⃣ 操作后队列的”尾指针”已经超出对队列的最大范围了,之后无法再进行入队操作,而队列实际空间并未占满,就造成了假溢出。

解决上溢的方法

1、将队中元素依次向队头方向移动。

  • 缺点:浪费时间。每移动一次, 队中元素都要移动

2、将队列空间设想成一个循环的表,即分配给队列的 m 个存储单元可以循环使用,当 rearMAXSIZE 时,若队列的开始端空着,又可从头使用空着的空间。当 frontMAXSIZE 时也是一样。

我们采用第2种方法

5️⃣:入队a7,q -> front = 2, q -> rear = 0

解决顺序队列假溢出

引入循环队列

base[0] 接在 base[MAXSIZE -1] 之后,若 rear + 1 == M,则令 rear = 0

实现方法: 利用 模(mod,C语言中: %)运算

插入元素:

// 队尾入队
q -> base[q -> rear] = data;
// 更新队尾指针
q -> rear = (q -> rear + 1) % MAXSIZE;

删除元素:

// 队头元素出队
data = q -> base[q -> front];
// 更新队头指针
q -> front = (q -> front + 1) % MAXSIZE;

循环队列判空、判满冲突

循环队列判满、判空解决方案

解决方案:

1.另外设一个标致以区别队空、队满

2.另设一个变量,记录元素个数

3.少用一个元素空间

本文实现的方法就是第三种。

少用一个元素空间的循环队列判满

循环队列常规操作

/********************* 循环队列的常规操作 **************************/

Queue    InitQueue();             	// 初始化循环队列
int      QueueFull();               // 循环队列判满
int      QueueEmpty();              // 循环队列判空
int      QueueLength();             // 求循环队列长度(元素个数)
int      EnQueue();                 // 循环队列 入队
int      DeQueue();                 // 循环队列 出队

void     QueueStatus();             // 打印队满、队空、队长状态
/****************************************************************/

定义循环队列结构体

#include "stdio.h"
#include "malloc.h"

#define TRUE 1
#define FALSE 0
#define MAXSIZE 10

typedef int ElemType;


// 定义循环队列结构体
typedef struct Queue{ 
   

	int *base;	// 队列首地址
	int front;	// 队列头下标
	int rear;	// 队列尾下标

}*Queue;

初始化循环队列

/* * 初始化循环队列 */
Queue InitQueue(){ 
   
    Queue q;
    // 分配循环队列空间
    q -> base = (ElemType *)malloc(sizeof(ElemType) * MAXSIZE);
    q -> front = q -> rear = 0;
    return q;
}

循环队列判满

/* * 循环队列判满 * q 循环队列 */
int QueueFull(Queue q){ 
   
    if(q == NULL){ 
   
        return FALSE;
    }
    return (q -> rear + 1) % MAXSIZE == q -> front;
}

循环队列判空

/* * 循环队列判空 * q 循环队列 */
int QueueEmpty(Queue q){ 
   
    if(q == NULL){ 
   
        return FALSE;
    }
    return q -> front == q -> rear;
}

计算循环队列的长度

/* * 计算循环队列长度 * q 循环队列 */
int QueueLength(Queue q){ 
   
    if(q == NULL){ 
   
        return FALSE;
    }
    return (q -> rear - q -> front + MAXSIZE) % MAXSIZE;
}

循环队列 入队(EnQueue)

/* * 循环队列 入队 * q 循环队列 * data 入队元素 */
int EnQueue(Queue q, ElemType data){ 
   
    if(QueueFull(q)){ 
   
        return FALSE;
    }
    // 队尾入队
    q -> base[q -> rear] = data;
    // 更新队尾指针
    q -> rear = (q -> rear + 1) % MAXSIZE;
    return TRUE;
}

循环队列 出队(DeQueue)

/* * 循环队列 出队 * q 循环队列 * *val 用来存出队元素的数据 */
int DeQueue(Queue q, ElemType *val){ 
   
    if(QueueEmpty(q)){ 
   
        return FALSE;
    }
    // 队头元素出队
    *val = q -> base[q -> front];
    // 更新队头指针
    q -> front = (q -> front + 1) % MAXSIZE;
    return TRUE;
}

循环队列各操作测试

/* * 打印队满、队空、队长状态 * q 循环队列 */
void QueueStatus(Queue q){ 
   
    printf("QueueFull():%d\n", QueueFull(q));
    printf("QueueEmpty():%d\n", QueueEmpty(q));
    printf("QueueLength():%d\n\n", QueueLength(q));
}

// 程序主入口
int main(int argc, char const *argv[])
{ 
      
    Queue q = InitQueue();
    printf("QueueMaxSize: %d\n\n", MAXSIZE);
    QueueStatus(q); // 打印队满、队空、队长状态

    // 入队
    printf("EnQueue():");
    for(int i = 1; i < MAXSIZE * 2; i+=2){ 
   
        printf("%d\t", i);
        EnQueue(q, i);
    }

    printf("\n");
    QueueStatus(q);

    // 出队
    int val;
    printf("DeQueue():");
    while(!QueueEmpty(q)){ 
   
        DeQueue(q, &val);
        printf("%d\t", val);
    }
    printf("\n");
    QueueStatus(q);

    // 测试循环队列是否会假溢出
    int num = 20;
    printf("EnQueue(%d): %d\t(0 Failed, 1 Success)\n", num, EnQueue(q, num));
    QueueStatus(q);
    return 0;
}

结果如下:

QueueMaxSize: 10

QueueFull():0
QueueEmpty():1
QueueLength():0

EnQueue():1     3       5       7       9       11      13      15      17      19
QueueFull():1
QueueEmpty():0
QueueLength():9

DeQueue():1     3       5       7       9       11      13      15      17
QueueFull():0
QueueEmpty():1
QueueLength():0

EnQueue(20): 1(0 Failed, 1 Success)
QueueFull():0
QueueEmpty():0
QueueLength():1

源代码

源代码已上传到 GitHub Data-Structure-of-C,欢迎大家下载 C语言实现数据结构

✍ 码字不易,记得点赞 ? 收藏 ⭐️

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138913.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • docker(7)docker-compose容器集群编排「建议收藏」

    docker(7)docker-compose容器集群编排「建议收藏」前言实际工作中我们部署一个应用,一般不仅仅只有一个容器,可能会涉及到多个,比如用到数据库,中间件MQ,web前端和后端服务,等多个容器。我们如果一个个去启动应用,当项目非常多时,就很难记住了,所有

  • 数据结构哈希表怎么画(数据结构哈希算法)

    数据结构哈希表参考代码如下:/* 名称:哈希表 语言:数据结构C语言版 编译环境:VC++6.0 日期:2014-3-26*/#include#include#include#defineNULLKEY0 //0为无记录标志#defineN10 //数据元素个数typedefintKeyType;//设关键字域为整型

  • 垃圾清理代码_一招清理电脑垃圾

    垃圾清理代码_一招清理电脑垃圾hello,大家好,我是你们的小雨哥哥。今天要教大家的是如何一键清理电脑的垃圾文件。众所周知,电脑用久了会越来越卡,运行的越来越慢,这其中除了硬件的损耗之外,还有一个原因就是电脑的垃圾文件越来越多,缓存文件越来越多。很多程序,例如浏览器,在使用过一次之后,为了下次打开的速度快一点,它会自动保留一下缓存文件,然后等待下来打开的时候就不用去请求服务器了,直接读取电脑本地的缓存…

  • 我是全网最硬核的高并发编程作者,CSDN最值得关注的博主,大家同意吗?(建议收藏)「建议收藏」

    我是全网最硬核的高并发编程作者,CSDN最值得关注的博主,大家同意吗?(建议收藏)「建议收藏」我是全网最硬核的高并发编程作者,CSDN最值得关注博主,全网最硬核的基于可视化的多数据源数据异构中间件作者,也许现在就是,也是不久的将来就是,大家同意吗?

  • 如何使用阿里云的NAS云文件存储服务「建议收藏」

    如何使用阿里云的NAS云文件存储服务「建议收藏」1.NAS云存储阿里云官方文档阿里云文件存储NAS(ApsaraFileStorage)是面向阿里云ECS实例、E-HPC和容器服务等计算节点的文件存储服务。它是一种可共享访问、弹性扩展、高可靠以及高性能的分布式文件系统。NAS基于POSIX文件接口,天然适配原生操作系统,提供共享访问,同时保证数据一致性和锁互斥。它提供了简单的可扩展文件存储以供与ECS配合使用,多个ECS实例可以同时访问NAS文件系统,并且存储容量会随着您添加和删除文件而自动弹性增长和收缩,为在多个实例或服务器上运行产生的工作负

发表回复

您的电子邮箱地址不会被公开。

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