第 3 章 栈和队列 (循环队列)

1. 背景说明

和顺序栈相类似,在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外,

尚需附设两个指针 front 和 rear 分别指示队列头元素及队列尾元素的位置。约定:初始化建空队列时,令 fronts = rear = 0,

每当插入新的队列尾元素时,“尾指针增 1”;每当删除队列头元素时,“头指针增 1”。因此,在非空队列中,头指针始终指向

队列头元素,而尾指针始终指向队列尾元素的下一个位置。 

2. 示例代码

1) status.h

/* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H
#define STATUS_H/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
#define ERR_FULL_QUEUE			10			/* 队列为满错 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */#endif // !STATUS_H

2) cycleQueue.h

/* 循环队列实现头文件 */#ifndef CYCLEQUEUE_H
#define CYCLEQUEUE_H#include "status.h"#define MAX_QUEUE_SIZE 5typedef int QElemType;typedef struct {QElemType *base;int front;int rear;
} SqQueue;/* 构造一个空队列 Q */
Status InitQueue(SqQueue *Q);/* 销毁队列 Q */
Status DestroyQueue(SqQueue *Q);/* 将 Q 清为空队列 */
void ClearQueue(SqQueue *Q);/* 若队列 Q 为空队列,则返回 TRUE,否则返回 FALSE */
Bollean QueueEmpty(const SqQueue *Q);/* 返回 Q 的元素个数,即队列的长度 */
int QueueLength(const SqQueue *Q);/* 若队列不空,则用 e 返回 Q 的队头元素,并返回 OK */
Status GetQueueHead(const SqQueue *Q, QElemType *e);/* 插入元素 e 为 Q 的新的队尾元素 */
Status EnQueue(QElemType e, SqQueue *Q);/* 若队列不空,则删除 Q 的队头元素,用 e 返回其值,并返回 OK */
Status DeQueue(SqQueue *Q, QElemType *e);/* 从队头到队尾依次对队列 Q 中每个元素调用函数 vi() */
Status QueueTraverse(const SqQueue *Q, void(*vi)(QElemType));#endif // !CYCLEQUEUE_H

3) cycleQueue.c

/* 循环队列实现源文件 */#include "cycleQueue.h"
#include <stdio.h>
#include <stdlib.h>static Bollean QueueFull(const SqQueue *Q)
{return (((Q->rear + 1) % MAX_QUEUE_SIZE) == Q->front) ? TRUE : FALSE;
}/* 构造一个空队列 Q */
Status InitQueue(SqQueue *Q)
{Q->base = (QElemType *)malloc(sizeof(QElemType) * MAX_QUEUE_SIZE);if (!Q->base) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);return ERR_MEMORY_ALLOCATE;}Q->front = Q->rear = 0;return RET_OK;
}/* 销毁队列 Q */
Status DestroyQueue(SqQueue *Q)
{if (Q->base) {free(Q->base);}Q->base = NULL;Q->front = Q->rear = 0;return RET_OK;
}/* 将 Q 清为空队列 */
void ClearQueue(SqQueue *Q)
{Q->front = Q->rear = 0;
}/* 若队列 Q 为空队列,则返回 TRUE,否则返回 FALSE */
Bollean QueueEmpty(const SqQueue *Q)
{return (Q->front == Q->rear) ? TRUE : FALSE;
}/* 返回 Q 的元素个数,即队列的长度, 模运算可以起到类似于绝对值的作用 */
int QueueLength(const SqQueue *Q)
{return ((Q->rear - Q->front + MAX_QUEUE_SIZE) % MAX_QUEUE_SIZE);
}/* 若队列不空,则用 e 返回 Q 的队头元素,并返回 OK */
Status GetQueueHead(const SqQueue *Q, QElemType *e)
{if (Q->front == Q->rear) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_QUEUE);return ERR_NULL_QUEUE;}*e = *(Q->base + Q->front);return RET_OK;
}/* 插入元素 e 为 Q 的新的队尾元素 */
Status EnQueue(QElemType e, SqQueue *Q)
{if (QueueFull(Q)) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_FULL_QUEUE);return ERR_FULL_QUEUE;}Q->base[Q->rear] = e;Q->rear = (Q->rear + 1) % MAX_QUEUE_SIZE;return RET_OK;
}/* 若队列不空,则删除 Q 的队头元素,用 e 返回其值,并返回 OK */
Status DeQueue(SqQueue *Q, QElemType *e)
{if (QueueEmpty(Q)) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_QUEUE);return ERR_NULL_QUEUE;}*e = Q->base[Q->front];Q->front = (Q->front + 1) % MAX_QUEUE_SIZE;return RET_OK;
}/* 从队头到队尾依次对队列 Q 中每个元素调用函数 vi() */
Status QueueTraverse(const SqQueue *Q, void(*vi)(QElemType))
{int pos = Q->front;while (pos != Q->rear) {vi(Q->base[pos]);pos = (pos + 1) % MAX_QUEUE_SIZE;}return RET_OK;
}

4) auxiliary.h

/* 辅助函数头文件 */#ifndef AUXILIARY_H
#define AUXILIARY_H#include "cycleQueue.h"/* 打印栈元素 */
void Print(QElemType e);#endif // !AUXILIARY_H

5) auxiliary.c

/* 辅助函数实现源文件 */#include "auxiliary.h"
#include <stdio.h>/* 打印栈元素 */
void Print(QElemType e)
{printf("%d ", e);
}

6) main.c

/* 入口程序源文件 */#include "status.h"
#include "auxiliary.h"
#include "cycleQueue.h"
#include <stdio.h>int main(void)
{SqQueue Q;int ret = InitQueue(&Q);if (ret != RET_OK) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);return ret;}printf("After initialize the queue, the queue is %s\n",(QueueEmpty(&Q) == TRUE) ? "empty" : "not empty");printf("Please input the element of the queue, no more than %d elements(-1 to break): ",MAX_QUEUE_SIZE - 1);QElemType e;int length = 0;do {scanf_s("%d", &e);if (e == -1) {break;}ret = EnQueue(e, &Q);if (ret != RET_OK) {break;}++length;} while (length < MAX_QUEUE_SIZE - 1);printf("The length of the queue is %d\n", QueueLength(&Q));printf("The queue is %s\n", (QueueEmpty(&Q) == TRUE) ? "empty" : "not empty");printf("Delete from the head of the queue and insert into the rear of the queue for"" %d times:\n", MAX_QUEUE_SIZE);for (int i = 0; i < MAX_QUEUE_SIZE; ++i) {DeQueue(&Q, &e);printf("The elment deleted is %d, please input the element to be insert: ", e);scanf_s("%d", &e);EnQueue(e, &Q);}printf("The element of the queue is: ");QueueTraverse(&Q, Print);printf("\n");length = QueueLength(&Q);if (length - 2 > 0) {printf("Now delete %d elements of the queue in the head of the queue\n", length - 2);}while (QueueLength(&Q) > 2) {DeQueue(&Q, &e);printf("The element of the queue deleted is %d\n", e);}ret = GetQueueHead(&Q, &e);if (ret == RET_OK) {printf("Now the element of the head of the queue is %d\n", e);}ClearQueue(&Q);printf("After clear the queue, the queue is %s\n", (QueueEmpty(&Q) == TRUE) ? "empty" : "not empty");DestroyQueue(&Q);return 0;
}

3. 输出示例

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全网都在用的nnUNet V2版本改进了啥,怎么安装?(一)

nnUNet&#xff0c;这个医学领域的分割巨无霸!在论文和比赛中随处可见他的身影。大家对于nnUNet v1版本的教程都赞不绝口&#xff0c;因为它简单易懂、详细全面&#xff0c;让很多朋友都轻松掌握了使用方法。 最近&#xff0c;我也抽出时间仔细研究了nnUNet v2&#xff0c;并全…

英国一大学宣布:严禁使用AI生成个人陈述

8月29日&#xff0c;伦敦都会大学&#xff08;London Met Uni&#xff09;在发给合作伙伴的邮件中表示&#xff1a;“我们知道人工智能技术已经被用来生成个人陈述&#xff08;personal statements&#xff0c;即文书&#xff09;。请注意&#xff0c;本大学不接受任何由人工智…

说说大表关联小表

分析&回答 Hive 大表和小表的关联 优先选择将小表放在内存中。小表不足以放到内存中&#xff0c;可以通过bucket-map-join(不清楚的话看底部文章)来实现&#xff0c;效果很明显。 两个表join的时候&#xff0c;其方法是两个join表在join key上都做hash bucket&#xff0c…

系统架构技能之设计模式-抽象工厂模式

一、上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点&#xff0c;我们现在来回顾一下&#xff1a; 简单工厂模式&#xff1a;一个工厂负责所有类型对象的创建&#xff0c;不支持无缝的新增新的类型对象的创建。 工厂模式&…

githubPage部署Vue项目

github中新建项目 my-web &#xff08;编写vue项目代码&#xff09; myWebOnline(存放Vue打包后的dist包里面的文件) 发布流程 &#xff08;假设my-web项目已经编写完成&#xff09;Vue-cli my-web vue.config.js文件中 const { defineConfig } require(vue/cli-service)…

求解整数规划问题的割平面法和分支定界法

文章目录 整数规划割平面法分支定界法代码实现 整数规划 整数规划问题是优化变量必须取整数值的线性或非线性规划问题&#xff0c;不过&#xff0c;在大多数情况下&#xff0c;整数规划问题指的是整数线性规划问题。 其数学模型为 m i n f ( x ) c T x s.t A x b x ≥ 0 x…

JVM类的加载过程

加载过程 JVM的类的加载过程分为五个阶段&#xff1a;加载、验证、准备、解析、初始化。 加载   加载阶段就是将编译好的的class文件通过字节流的方式从硬盘或者通过网络加载到JVM虚拟机当中来。&#xff08;我们平时在Idea中书写的代码就是放在磁盘中的&#xff0c;也可以通…

Mysql主从服务安装配置

1.下载地址 MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/ 2.安装配置 1.下载解压后&#xff0c;拷贝一份作为slave的安装目录 3.配置my.ini 由于下载mysql8版本&#xff0c;解压后&#xff0c;没有相关的my…

Spark有两种常见的提交方式:client 模式和 cluster 模式对机器 CPU 的影响

Spark有两种常见的提交方式&#xff1a;client 模式和 cluster 模式。这两种方式对机器 CPU 的影响略有不同 &#xff0c;请参考以下说明 Client 模式&#xff1a; 在 Client 模式下&#xff0c;Spark Driver 运行在提交任务的客户端节点上&#xff08;即运行 spark-submit 命…

企业数据加密软件——「天锐绿盾」

「天锐绿盾」是一款企业数据加密软件&#xff0c;主要用于防止企业计算机信息被破坏、丢失和泄密。该软件采用文件过滤驱动实现透明加解密&#xff0c;对用户完全透明&#xff0c;不影响用户操作习惯。 PC访问地址&#xff1a; isite.baidu.com/site/wjz012xr/2eae091d-1b97-4…

Laravel 模型1对1关联 1对多关联 多对多关联 ⑩①

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; THINK PHP &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

DNS原理

文章目录 一、域名产生背景域名的树形层次化结构 二、定义三、DNS查询模式递归查询迭代查询 四、主机域名解析工作流程五、H3C配置DNS代理 首先可以看下思维导图&#xff0c;以便更好的理解接下来的内容。 一、域名 产生背景 在互联网中&#xff0c;通过IP地址访问目标主机…

Python:多变量赋值

相关文章 Python专栏https://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 Python中的赋值语句可以同时对多个变量进行对象绑定&#xff08;赋值&#xff09;&#xff0c;既可以是多变量链式赋值&#xff0c;也可以是多变量平行赋值&#x…

【LeetCode75】第四十二题 删除二叉搜索数中的节点

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一棵二叉搜索树&#xff0c;给我们一个目标值&#xff0c;让我们删除节点值等于目标值的节点&#xff0c;并且删除之后需要保持…

React 18 在组件间共享状态

参考文章 在组件间共享状态 有时候&#xff0c;希望两个组件的状态始终同步更改。要实现这一点&#xff0c;可以将相关 state 从这两个组件上移除&#xff0c;并把 state 放到它们的公共父级&#xff0c;再通过 props 将 state 传递给这两个组件。这被称为“状态提升”&#…

ELK安装、部署、调试(一)设计规划及准备

一、整体规划如图&#xff1a; 【filebeat】 需要收集日志的服务器&#xff0c;安装filebeat软件&#xff0c;用于收集日志。logstash也可以收集日志&#xff0c;但是占用的系统资源过大&#xff0c;所以使用了filebeat来收集日志。 【kafka】 接收filebeat的日志&#xff…

Docker从认识到实践再到底层原理(二-1)|容器技术发展史+虚拟化容器概念和简介

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

数据结构(Java实现)-Map和Set

搜索树 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左右子树也…

Python爬虫-某网酒店数据

前言 本文是该专栏的第5篇,后面会持续分享python爬虫案例干货,记得关注。 本文以某网的酒店数据为例,实现根据目标城市获取酒店数据。具体思路和方法跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93d3cuYnRoaG90ZWxzLmNvbS9saXN0L3NoYW5naGFp …

105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 思路&#xff1a;题目给出了先序遍历和中序遍历的结果&#xff0c;因为先序遍历遵循根–>左–>…