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

这篇具有很好参考价值的文章主要介绍了第 3 章 栈和队列 (循环队列)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 背景说明

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

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

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

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

第 3 章 栈和队列 (循环队列),# 数据结构(C语言版),c语言,算法,数据结构

第 3 章 栈和队列 (循环队列),# 数据结构(C语言版),c语言,算法,数据结构第 3 章 栈和队列 (循环队列),# 数据结构(C语言版),c语言,算法,数据结构

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 5

typedef 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. 输出示例

第 3 章 栈和队列 (循环队列),# 数据结构(C语言版),c语言,算法,数据结构文章来源地址https://www.toymoban.com/news/detail-694472.html

到了这里,关于第 3 章 栈和队列 (循环队列)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言数据结构——线性表之栈和队列

    为什么会定义栈和队列这两种数据结构呢? 原因在于: 之所以会定义栈和队列这样的数据结构 是因为他们有两大特性 : 第一: 他们可以保存程序运行路径中各个点的信息,以便用于回溯操作或其他需要访问已经访问过的节点信息的操作。 比如: 栈用于解决迷宫问题,就

    2023年04月11日
    浏览(113)
  • 数据结构入门(C语言版)栈和队列之队列的介绍及实现

    什么是队列呢?我们先看下面的图: 我们可以理解成高速公路上的隧道,根据这个图的描述 我们把需入队的元素看作一辆车,把队列看作隧道,由此我们可以看出 队列的特点是 只允许从一端进入,从另一端离开。 队列就是只允许在一端进行插入数据操作,在另一端进行删

    2023年04月15日
    浏览(44)
  • 数据结构--》深入了解栈和队列,让算法更加高效

            本文将带你深入了解数据结构栈和队列,这两种基础的线性数据结构在算法中的重要性不言而喻。我们将会详细介绍栈和队列的概念、分类、实现以及应用场景,在理解栈和队列的基础上,还将探讨如何通过栈和队列来高效地解决算法问题。         无论你是

    2024年02月10日
    浏览(40)
  • 【数据结构和算法】--队列的特殊结构-循环队列

    循环队列是队列的一种特殊结构,它的 长度是固定的 k ,同样是 先进先出 ,理论结构是 首尾相连的环形循环结构 。其理论结构大致如下: 具体结构描述可以参考 LeetCode : 622. 设计循环队列的题目要求,大致如下: 设计你的循环队列实现。 循环队列是一种 线性数据结构 ,

    2024年02月04日
    浏览(49)
  • 【数据结构】—手把手带你用C语言实现栈和队列(超详细!)

                                       食用指南:本文在有C基础的情况下食用更佳                                     🔥 这就不得不推荐此专栏了:C语言                                   ♈️ 今日夜电波:Tell me —milet                    

    2024年02月14日
    浏览(119)
  • 【数据结构与算法分析】使用C语言实现队列的两种(带头结点与不带头结点)链式存储,并且给出一种循环队列的设计思想

      当我们编写程序时,经常需要处理各种数据结构。队列是一种常见的数据结构,它有着广泛的应用场景。队列的基本操作包括入队和出队,应用于模拟等待队列、消息队列、计算机缓存等场合。   在实际编程中,我们可以用不同的数据结构来实现队列。本文主要介绍了

    2024年02月08日
    浏览(118)
  • 【数据结构与算法】设计循环队列

      🧑‍🎓 个人主页:简 料   🏆 所属专栏:C++   🏆 个人社区:越努力越幸运社区   🏆 简       介: 简料简料,简单有料~在校大学生一枚,专注C/C++/GO的干货分享,立志成为您的好帮手 ~ C/C++学习路线 (点击解锁) ❤️ C语言阶段(已结束) ❤️ 数据结构与算法(ing) ❤

    2024年01月17日
    浏览(45)
  • 数据结构(C语言实现)——栈和队列的介绍及基本操作的实现(动态顺序栈+链队)

    今天我们来学习另外两个线性结构——栈和队列,栈和队列是操作受限的线性表,因此,可称为限定性的数据结构。 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守

    2023年04月19日
    浏览(44)
  • 数据结构-循环队列详解(c语言版)

    目录 一、什么是循环队列? 二、特点 三、基本运算 四、代码实现  1、初始化 2、入队 3、出队 4、队满? 5、队空?  6、输出队列 7、队列大小 8、获取队首元素 五、队列应用场景 六、完整代码 1、完整代码 2、运行结果 七、总结 前言 相比于链队列, 循环队列 有着内存固

    2024年01月20日
    浏览(56)
  • 【数据结构与算法】03 队列(顺序队列--循环队列--优先级队列--链队列)

    队列( queue )是一种常见的数据结构,它遵循先进先出(FIFO)的原则。队列可以理解为一个具有两个端点的线性数据结构,其中一个端点称为\\\"队尾\\\"(rear),用于插入新元素,另一个端点称为\\\"队首\\\"(front),用于移除元素。新元素被插入到队尾,而最早插入的元素总是在队

    2024年02月08日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包