c++数据结构之队列

news2025/3/13 17:27:25

目录

一、队列的含义

1.队列的使用

2.队列的结构  

二、顺序队列的实现

1.队列的定义

2.队列的初始化

3.清空对列

4.队列是否为空

5.获取队列的长度

6.获取头元素的值

7.入队列

8.出队列

9.遍历队列中的值

10.总代码

11.打印结果

三、链表队列的实现

1.队列的初始化

2.销毁队列

3.清理队列

4.队列是否为空

5.求队列的长度

6.获取头节点的值

7.出队列

8.入队列

9.遍历队列

10.全代码

11.打印测试


一、队列的含义

1.队列的使用

         我们在用电脑时有没有经历过,机器有时会处于疑似死机的状态,鼠标点什么似乎都没用,双击任何快捷方式都不动弹。就当你失去耐心,打算关机,突然它就像醒了一样,把你刚才点击的所有操作全部都按顺序执行了一遍。这其实是因为操作系统中的多个程序因需要通过一个通道输出,而按先后次序排队等待造成的。

         再比如像移动、联通、电信等客服电话,客服人员与客户相比总是少数,在所有的客服人员都占线的情 况下,客户会被要求等待,直到有某个客服人员空下来,才能让最先等待的客户接通电话。这里也是将 所有当前拨打客服电话的客户进行了排队处理。        

2.队列的结构  

        队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表

        队列是一种先进先出的线性表,简称 FIFO。允许插入的一端称为队尾,允许删 除的一端称为队头。 这里从队列中的定义中,不难看出队列和栈一样也都是一种线性表,也就是说队有顺序队列和链式队两大类。        

二、顺序队列的实现

        因为顺序对列中,队列中的大小是固定的,在 tail 指针插满后,它会从0开始继续插入元素,所以说它是环形插入的,因此要考虑三种情况。在实现顺序队列之前,我们先看三张图,分别代表顺序队列的三种情况。

        第一种:head 指针 == tail 指针,此时队列中元素为空。

        第二种:head 指针 < tail 指针,此时Tail指针还没有到队列尾部。

        第三种:head 指针 > tail 指针,此时Tail指针到达队列尾部后,继续从头开始插入

1.队列的定义

        主要完成对队列的定义和一些常量的定义。

#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;

typedef struct
{
	ElemType data[MAX_SIZE];
	int front;    // 头指针: 用来出栈
	int rear;     // 尾指针: 用来入栈
}SqQueue;
2.队列的初始化

        以为用的是双指针来代表队列,所以直接等于0就行。

// 初始化队列
Status InitQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}
3.清空对列

        和队列的初始化一样。

// 清空队列
Status ClearQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}
4.队列是否为空
// 队列是否为空
Status QueueEmpty(SqQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}
5.获取队列的长度
// 获取队列的长度
int QueueLength(SqQueue Q)
{
	// 需要考虑三种情况
	return (Q.rear - Q.front + MAX_SIZE) % MAX_SIZE;
}
6.获取头元素的值
// 获取头元素的值
Status GetHead(SqQueue Q, ElemType* e)
{
	if (Q.front == Q.rear) return ERROR;
	*e = Q.data[Q.front];
    return OK;
}
7.入队列
// 入队列
Status EnQueue(SqQueue* Q, ElemType e)
{
	// 判断是否满了
	if (((Q->rear + 1) % MAX_SIZE) == MAX_SIZE) return ERROR;
    Q->data[Q->rear] = e;
	Q->rear = (Q->rear + 1) % MAX_SIZE;
	return OK;
}
8.出队列
// 出队列
Status DeQueue(SqQueue* Q, ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAX_SIZE;

	return OK;
}
9.遍历队列中的值
// 打印队列中的值
Status QueueTraverse(SqQueue Q)
{
	int i = Q.front;
	while (i != Q.rear)
	{
		if (i != Q.front) printf("->");
		printf("%d", Q.data[i]);
		i = (i + 1) % MAX_SIZE;
	}
	printf("\n");
	return OK;
}
10.总代码
#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;

typedef struct
{
	ElemType data[MAX_SIZE];
	int front;    // 头指针: 用来出栈
	int rear;     // 尾指针: 用来入栈
}SqQueue;

// 初始化队列
Status InitQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}

// 清空队列
Status ClearQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}

// 队列是否为空
Status QueueEmpty(SqQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}


// 获取队列的长度
int QueueLength(SqQueue Q)
{
	// 需要考虑三种情况
	return (Q.rear - Q.front + MAX_SIZE) % MAX_SIZE;
}


// 获取头元素的值
Status GetHead(SqQueue Q, ElemType* e)
{
	if (Q.front == Q.rear) return ERROR;
	*e =  Q.data[Q.front];
	return OK;
}


// 入队列
Status EnQueue(SqQueue* Q, ElemType e)
{
	// 判断是否满了
	if (((Q->rear + 1) % MAX_SIZE) == MAX_SIZE) return ERROR;
	Q->data[Q->rear] = e;
	Q->rear = (Q->rear + 1) % MAX_SIZE;
	return OK;
}

// 出队列
Status DeQueue(SqQueue* Q, ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAX_SIZE;
	return OK;
}

// 打印队列中的值
Status QueueTraverse(SqQueue Q)
{
	int i = Q.front;
	while (i != Q.rear)
	{
		if (i != Q.front) printf("->");
		printf("%d", Q.data[i]);
		i = (i + 1) % MAX_SIZE;
	}
	printf("\n");
	return OK;
}


int main()
{
	Status j;
	int i = 0;
	ElemType d;
	SqQueue Q;
	InitQueue(&Q);
	printf("初始化队列后,队列空否?%u(1:空 0:否)\n", QueueEmpty(Q));
	do
	{
		d = (i++) + 100;
		EnQueue(&Q, d);
	} while (i < MAX_SIZE - 1);
	printf("队列长度为: %d\n", QueueLength(Q));
	printf("现在队列中的元素为: \n");
	QueueTraverse(Q);
	while (QueueLength(Q) > 2)
	{
		DeQueue(&Q, &d);
		printf("删除的元素值为%d\n", d);
	}
	j = GetHead(Q, &d);
	if (j)
		printf("现在队头元素为: %d\n", d);
	ClearQueue(&Q);
	printf("清空队列后, 队列空否?%u(1:空 0:否)\n", QueueEmpty(Q));
	return 0;
}

11.打印结果

三、链表队列的实现

        如下图所示,Head 头节点data为 NULL,next 指向 节点值为2的节点。Tail 尾节点就等于值为 5 的节点。

1.队列的初始化
#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;


typedef struct QNode
{
	ElemType data;
	QNode* next;
}*QueuePtr;

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue* Q)
{
	Q->front = (QueuePtr)malloc(sizeof(QNode));
	Q->rear = Q->front;
	if (Q->front == NULL)
	{
		return ERROR;
	}

	Q->front->next = NULL;
	return OK;
}
2.销毁队列
Status DestoryQueue(LinkQueue* Q)
{
	while (Q->front)
	{
		Q->rear = Q->front->next;
		free(Q->front);
		Q->front = Q->rear;
	}
	return OK;
}
3.清理队列
Status ClearQueue(LinkQueue* Q)
{
	// 让头节点和尾节点回到初始化的状态
	QueuePtr q, p;
	Q->rear = Q->front;
	p = Q->front->next;
	Q->front->next = NULL;
	while (p) 
	{
		q = p;
		p = p->next;
		free(q);
	}
	return OK;
}
4.队列是否为空
Status QueueEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}
5.求队列的长度
int QueueLength(LinkQueue Q)
{
	int count = 0;
	QueuePtr p = Q.front;
	while (p != Q.rear && p != NULL)
	{
		p = p->next;
		count++;
	}
	return count;
}
6.获取头节点的值
Status GetHead(LinkQueue Q,ElemType* e)
{
	QueuePtr p;
	if (Q.front == Q.rear) return ERROR;
	p = Q.front->next;
	*e = p->data;
	return OK;
}
7.出队列

Status DeQueue(LinkQueue* Q,ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	QueuePtr temp = Q->front->next;
	*e = temp->data;
	Q->front->next = temp->next;
	// 判断以下: 如果 尾节点 = temp,让头节点与尾节点相等
	if (Q->rear == temp)  Q->rear = Q->front;
	free(temp);
	return OK;
}
8.入队列
Status EnQueue(LinkQueue* Q,ElemType e)
{
	QueuePtr temp;
	temp = (QueuePtr)malloc(sizeof(QNode));
	temp->data = e;
	temp->next = NULL;
	Q->rear->next = temp;
	Q->rear = temp;
	return OK;
}
9.遍历队列
Status QueueTraverse(LinkQueue Q)
{
	QueuePtr temp = Q.front->next;
	while (temp)
	{
		if (temp != Q.front->next) printf("->");
		printf("%d", temp->data);
		temp = temp->next;
	}
	printf("\n");
	return OK;
}
10.全代码

#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;


typedef struct QNode
{
	ElemType data;
	QNode* next;
}*QueuePtr;

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue* Q)
{
	Q->front = (QueuePtr)malloc(sizeof(QNode));
	Q->rear = Q->front;
	if (Q->front == NULL)
	{
		return ERROR;
	}

	Q->front->next = NULL;
	return OK;
}

Status DestoryQueue(LinkQueue* Q)
{
	while (Q->front)
	{
		Q->rear = Q->front->next;
		free(Q->front);
		Q->front = Q->rear;
	}
	return OK;
}

Status ClearQueue(LinkQueue* Q)
{
	// 让头节点和尾节点回到初始化的状态
	QueuePtr q, p;
	Q->rear = Q->front;
	p = Q->front->next;
	Q->front->next = NULL;
	while (p) 
	{
		q = p;
		p = p->next;
		free(q);
	}
	return OK;
}

Status QueueEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}

int QueueLength(LinkQueue Q)
{
	int count = 0;
	QueuePtr p = Q.front;
	while (p != Q.rear && p != NULL)
	{
		p = p->next;
		count++;
	}
	return count;
}

Status GetHead(LinkQueue Q,ElemType* e)
{
	QueuePtr p;
	if (Q.front == Q.rear) return ERROR;
	p = Q.front->next;
	*e = p->data;
	return OK;
}

Status EnQueue(LinkQueue* Q,ElemType e)
{
	QueuePtr temp;
	temp = (QueuePtr)malloc(sizeof(QNode));
	temp->data = e;
	temp->next = NULL;
	Q->rear->next = temp;
	Q->rear = temp;
	return OK;
}

Status DeQueue(LinkQueue* Q,ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	QueuePtr temp = Q->front->next;
	*e = temp->data;
	Q->front->next = temp->next;
	// 判断以下: 如果 尾节点 = temp,让头节点与尾节点相等
	if (Q->rear == temp)  Q->rear = Q->front;
	free(temp);
	return OK;
}

Status QueueTraverse(LinkQueue Q)
{
	QueuePtr temp = Q.front->next;
	while (temp)
	{
		if (temp != Q.front->next) printf("->");
		printf("%d", temp->data);
		temp = temp->next;
	}
	printf("\n");
	return OK;
}


int main()
{
	int i;
	ElemType d;
	LinkQueue q;
	i = InitQueue(&q);
	if (i)
		printf("成功地构造了一个空队列!\n");
	printf("是否空队列?%d(1:空 0:否) ", QueueEmpty(q));
	printf("队列的长度为%d\n", QueueLength(q));
	EnQueue(&q, -5);
	EnQueue(&q, 5);
	EnQueue(&q, 10);
	printf("插入 3 个元素(-5,5,10)后,队列的长度为%d\n", QueueLength(q));
	printf("是否空队列?%d(1:空 0:否) ", QueueEmpty(q));
	printf("队列的元素依次为:");
	QueueTraverse(q);
	i = GetHead(q, &d);
	if (i == OK)
		printf("队头元素是:%d\n", d);
	DeQueue(&q, &d);
	printf("删除了队头元素%d\n", d);
	printf("队列的元素依次为:");
	QueueTraverse(q);
	i = GetHead(q, &d);
	if (i == OK)
		printf("新的队头元素是:%d\n", d);
	ClearQueue(&q);
	printf("销毁队列后,q.front=%u q.rear=%u\n", q.front, q.rear);
	return 0;
}

11.打印测试

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Hot100】LeetCode—347. 前 K 个高频元素

目录 1- 思路自定义Node结点 哈希表实现 2- 实现⭐347. 前 K 个高频元素——题解思路 3- ACM实现 原题连接&#xff1a;347. 前 K 个高频元素 1- 思路 自定义Node结点 哈希表实现 ① 自定义 Node 结点&#xff1a; 自定义 Node 结点中有 value 和 cnt 字段&#xff0c;其中…

力扣接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

html css网页制作

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; HTML 和 CSS 是制作网页的基础。HTML 用于定义网页的结构和内容&#xff0c;CSS 用于设计网页的样式和布局。以下是一个详细的网页制作成品教程&#xff0c;包括 HTML 和 CSS 的基础知识&#xff0c;及如何…

MySQL基础(7)- 多表查询

目录 一、笛卡尔积的错误与正确的多表查询 1.出现笛卡尔积错误 2.正确的多表查询&#xff1a;需要有连接条件 3.查询多个表中都存在的字段 4.SELECT和WHERE中使用表的别名 二、等值连接vs非等值连接、自连接vs非自连接 1.等值连接 vs 非等值连接 2.自连接 vs 非自连…

安卓逆向(之)真机root(红米手机)

概览&#xff1a; 1, 手机解锁 2, 下载官方系统包&#xff0c;推荐线刷包,取出镜像文件 3, magisk工具修补 官方系统包 4, adb&#xff1a;命令对手机刷 root 5, 完成 6, 小米手机解锁 点击 小米手机解锁OEM官方教程 记得数据线连接手机电脑 工具下载 点击 下载adb(电脑操作…

进程间通信-进程池

目录 理解​ 完整代码 完善代码 回收子进程&#xff1a;​ 不回收子进程&#xff1a; 子进程使用重定向优化 理解 #include <iostream> #include <unistd.h> #include <string> #include <vector> #include <sys/types.h>void work(int rfd) {…

Windows下使用cmake编译OpenCV

Windows下使用cmake编译OpenCV cmake下载OpenCV下载编译OpenCV cmake下载 下载地址&#xff1a;https://cmake.org/download/ 下载完成&#xff0c;点击选择路径安装即可 OpenCV下载 下载地址&#xff1a;https://github.com/opencv/opencv/releases/tag/4.8.1因为我们是编译…

2024软件测试需要具备的技能(软技能硬技能)

软件测试的必备技能 在往期的文章分享了很多的面试题&#xff0c;索性做一个转型。从零基础开始讲解&#xff0c;结合面试题来和大家一起学习交流软件测试的艺术。 第一个是专业技能&#xff0c;也叫硬技能。 第二个叫做软技能。 我们在上一篇文章中讲到了软件测试流程的5个…

ChatGPT在论文写作领域的应用:初稿设计

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 学术论文写作中&#xff0c;内容清晰、结构合理的初稿至关重要。通过 ChatGPT&#xff0c;写作者可以快速生成内容框架、明确研究问题&#xff0c;并优化表达方式。不仅提高了写作效率&…

笔记整理—内核!启动!—kernel部分(1)驱动与内核的关系

首先&#xff0c;恭喜完成了uboot部分的内容整理&#xff0c;其次补充一点&#xff0c;uboot第一部分和第二部分的工作不是一定的&#xff0c;在不同的版本中&#xff0c;可能这个初始化早一点&#xff0c;那个的又放在了第二部分&#xff0c;版本不同&#xff0c;造成的工作顺…

滑动窗口——632. 最小区间

最近在抽时间写LC上的一个专栏——2024春招冲刺百题计划。挑着做&#xff0c;做了几道和滑动窗口相关的题目&#xff0c;632. 最小区间&#xff0c;LC上标记为困难&#xff0c;第一次写完全没有思考&#xff0c;参考了别人写的答案茅塞顿开&#xff0c;特此记录以鞭策自己学习。…

Android perfetto 简介

Android perfetto 简介 使用 perfetto 工具&#xff0c;您可以通过 Android 调试桥 (adb) 在 Android 设备上收集性能信息。使用 adb shell perfetto ... 命令调用 perfetto 工具。 perfetto 从您的设备上收集性能跟踪数据时会使用多种来源&#xff0c;例如&#xff1a; 使用…

5、const修饰类型和变量

const修饰类型和变量 一、const常量一些注意点1、声明时必须同时初始化2、不可更改3、与宏常量的区别 二、const修饰指针1、常量指针constant pointer2、常指向指针pointer-to-constant pointer 一、const常量一些注意点 1、声明时必须同时初始化 #include <iostream> …

框架template初识

框架初识 框架就是一个别人帮我们搭好的舞台&#xff0c;造好了很多现成的工具供我们使用&#xff0c;让开发过程更快速、简洁。 Gin框架介绍 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 Gin是一个用Go语言编写的web框架。它是一个类似于martini 但拥有更好性能的API…

企业网银登录提示请确认您已插入工商银行U盾证书的解决方法

昨天受人之托帮小企业财务解决上网银的问题 因为不是专业做这个的&#xff0c;所以只能安装“常识”行事&#xff0c;但结果实在是令人意想不到。 排错的步骤&#xff1a; 同一台电脑上尝试不同浏览器&#xff0c;发现360浏览器的接受度相当普遍&#xff1b;给U盾换不同的连接…

抖音引流脚本工具,实现自动化引流,解放大家双手

抖音引流脚本工具,实现自动化引流,解放大家双手 #获客引流 推荐阅读&#xff1a; 百收网SEO引流脚本软件不断更新&#xff08;推广全集教程&#xff09;https://www.bsw80.com/post/460.html 我们这篇文章的话&#xff0c;来去给大家说一下这个抖音这个同城评论&#xff0c;…

探索 RAD:5 个最佳实践案例解析

天下武功&#xff0c;唯快不破&#xff01;应用开发&#xff0c;唯速称王&#xff01; 在当今快速发展的科技环境中&#xff0c;企业面临的挑战不断升级。传统的应用开发方法往往因其复杂的流程和较长的开发周期而无法满足快速变化的市场需求。在这种背景下&#xff0c;快速应…

【阿里云】个人认证与公司认证

个人认证和企业认证的区别 更新时间&#xff1a;2024-05-20 09:32:52 本文档主要介绍个人认证账号和企业认证账号的区别。 账号实名认证分为个人实名认证和企业实名认证。 个人账号认证&#xff0c;请选择认证类型为 个人&#xff0c;支持个人支付宝授权认证和个人扫脸认证。…

如何免费将视频转换为 MP4?将视频转换为 MP4 的 5 种方法

您知道如何免费将不受支持的视频格式转换为 MP4 吗&#xff1f; 您可以轻松地在视频共享网站和社交应用上访问各种视频。从网站下载视频但无法使用媒体播放器播放是很常见的事。如何将视频转换为 MP4以便更好地播放&#xff1f; 事实上&#xff0c;市场上有很多视频音频转换工…

【Python 千题 —— 算法篇】字符统计

Python 千题持续更新中 …… 脑图地址 &#x1f449;&#xff1a;⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 在编程中&#xff0c;对字符串的字符统计是一个常见任务。这在文本处理、数据分析、词频统计、自然语言处理等领域有广泛应用。无论…