【数据结构】14 队列(带头结点的链式存储和顺序存储实现)

news2024/11/22 20:09:57

定义

队列是一个有序线性表,但是队列的插入、删除操作是分别在线性表的两个不同端点进行的。
设一个队列 Q = ( a 1 , a 2 , . . . , a n ) Q = (a_1, a_2,...,a_n) Q=(a1,a2,...,an),那么 a 1 a_1 a1被称为队头元素, a n a_n an为队尾元素。假如将元素A,B,C,D依次插入队列,第一个从队列中删除的元素为A,即先插入的将被先删除,故队列也称为先进先出表。

抽象数据类型
类型名称:队列
数据对象集:一个有0个或者多个元素的有穷线性表
操作集:对于一个长度为正整数MaxSize的队列 Q Q Q, 记队列中的任一元素 X X X,队列的基本操作集为:

  1. Queue CreateQueue(int MaxSize)
  2. bool IsFull(Queue Q)
  3. bool AddQ(Queue Q, ElementType X)
  4. bool Is Empty(Queue Q)
  5. ElementType DeleteQ(Queue Q)

队列的顺序存储实现

队列的最简单的表示方法是用数组。用数组存储队列有许多具体的方法。一般可以选择将队列头放数组下标小的位置,而将队列尾放在数组下标大的位置,并用两个变量Front和Rear分别指示队列的头和尾。一般把Front和Rear先初始化为-1。当有元素入队时,Rear向右移动一格,放入队尾元素;当有元素出队时,先将Front向右移动一格,再删除队首元素。
在这里插入图片描述
随着入队出队的进行会使整个队列整体向后移动这样就出现了如上图所示的现象,指针已经移到了最后,在再有元素入队时就会出现溢出,可是事实上此时队中并未真的满员,这种现象称为假溢出。

为了解决队尾溢出而实际上数组中仍有空余空间的问题,一般在队列的顺序存储结构中采用循环队列的方式,队尾指针和队首指针到达数组端点时能折回到数组开始处即相当于将数组头尾相接想象成环形,如图所示当插入和删除操作的作用单元达到数组的末端后用公式"Rear % 数组长度"取余运算就可以实现折返到起始单元。
在这里插入图片描述
队列初始化时,将Front和Rear都初始化为0,当插入一个元素时,Rear+1,删除一个元素时,Front加一。
当Front = Rear时,队列为空。
当队尾指针加1就会从后面赶上头指针,(Rear + 1)%数组长度 = Front
在这里插入图片描述

代码实现

顺序存储

数据结构

typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode {
	ElementType* Data;
	Position Front, Rear;
	int MaxSize;
};
typedef PtrToQNode Queue;

创建循环队列

Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	Q->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);
	Q->Front = 0;
	Q->Rear = 0;
	return Q;
}

插入元素


bool IsFull(Queue Q) {
	if ((Q->Rear + 1) % Q->MaxSize == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}

bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}
	else {
		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

删除元素

bool IsEmpty(Queue Q) {
	if (Q->Rear == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}


ElementType DeleteQ(Queue Q) {
	if (IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {
		Q->Front = (Q->Front + 1) % (Q->MaxSize);
		return Q->Data[(Q->Front)];


	}
}

完整代码

# include <stdio.h>
#include < stdlib.h>
#include <ctype.h>
#include <string.h>

typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode {
	ElementType* Data;
	Position Front, Rear;
	int MaxSize;
};
typedef PtrToQNode Queue;


Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	Q->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);
	Q->Front = 0;
	Q->Rear = 0;
	return Q;
}

bool IsFull(Queue Q) {
	if ((Q->Rear + 1) % Q->MaxSize == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}


bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}
	else {
		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}


void printQ(Queue Q) {
	int f = Q->Front;
	int r = Q->Rear;
	while (f != r) {
		f = (f + 1) % (Q->MaxSize);
		printf("QNode: %d\n", Q->Data[f]);
	}
}

bool IsEmpty(Queue Q) {
	if (Q->Rear == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}


ElementType DeleteQ(Queue Q) {
	if (IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {
		Q->Front = (Q->Front + 1) % (Q->MaxSize);
		return Q->Data[(Q->Front)];


	}
}

int main() {

	Queue Q = CreateQueue(10);
	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (AddQ(Q, X) == false) {
			printf("Add error!\n");
		}

	}

	printQ(Q);
	while (!IsEmpty(Q)) {
		ElementType out = DeleteQ(Q);
		printf("Out : %d\n", out);
		printf("\n");
		printQ(Q);
	}
	



}

链式存储

队列的头必须指向的是队列的头结点,队尾指向链表的尾节点

数据结构

typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {
	ElementType Data;
	PtrToNode Next;
};

typedef struct Node* Position;

struct QNode {
	Position Rear, Front;
	int MaxSize;
};
typedef struct QNode * Queue;

队列的创建

Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	PtrToNode L = (PtrToNode)malloc(sizeof(struct Node));
	
	L->Next = NULL;
	Q->Front = L;
	Q->Rear = L;

	
	printf("finish!\n");

	return Q;


}

加入元素


bool IsFull(Queue Q) {
	int cnt = 0;
	
	Position t = Q->Front;
	
	while (t != Q->Rear) {
		t = t->Next;
		cnt++;
	}
	printf("cnt : %d\n", cnt);
	if (cnt == Q->MaxSize) {
		return true;
	}
	else {
		return false;
	}
}


bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}

	Position R = Q->Rear;
	while (R->Next != NULL) {
		R = R->Next;
	}
	PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));
	t->Data = X;
	t->Next = R->Next;
	R->Next = t;
	Q->Rear = t;

	return true;


}

删除元素


bool IsEmpty(Queue Q) {
	if (Q->Front->Next == NULL) {
		return true;
	}
	else {
		return false;
	}
}

ElementType DeleteQ(Queue Q) {
	if(IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {

		ElementType t = Q->Front->Next->Data;
		Position te = Q->Front;
		Q->Front->Next = Q->Front->Next->Next;
		return t;
	}
}

完整代码

# include <stdio.h>
#include < stdlib.h>
#include <ctype.h>
#include <string.h>

typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {
	ElementType Data;
	PtrToNode Next;
};

typedef struct Node* Position;

struct QNode {
	Position Rear, Front;
	int MaxSize;
};
typedef struct QNode * Queue;


Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	PtrToNode L = (PtrToNode)malloc(sizeof(struct Node));
	
	L->Next = NULL;
	Q->Front = L;
	Q->Rear = L;

	
	printf("finish!\n");

	return Q;


}

bool IsFull(Queue Q) {
	int cnt = 0;
	
	Position t = Q->Front;
	
	while (t != Q->Rear) {
		t = t->Next;
		cnt++;
	}
	printf("cnt : %d\n", cnt);
	if (cnt == Q->MaxSize) {
		return true;
	}
	else {
		return false;
	}
}


bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}

	Position R = Q->Rear;
	while (R->Next != NULL) {
		R = R->Next;
	}
	PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));
	t->Data = X;
	t->Next = R->Next;
	R->Next = t;
	Q->Rear = t;

	return true;


}

void printq(Queue Q) {
	Position t = Q->Front;
	while (t != Q->Rear)
	{
		t = t->Next;
		printf("QNode: %d\n", t->Data);
	}

}

bool IsEmpty(Queue Q) {
	if (Q->Front->Next == NULL) {
		return true;
	}
	else {
		return false;
	}
}

ElementType DeleteQ(Queue Q) {
	if(IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {

		ElementType t = Q->Front->Next->Data;
		Position te = Q->Front;
		Q->Front->Next = Q->Front->Next->Next;
		return t;
	}
}

int main() {

	Queue Q = CreateQueue(10);

	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (AddQ(Q, X) == false) {
			printf("Add error!\n");
		}

	}

	printq(Q);
	while (!IsEmpty(Q)) {
		int out = DeleteQ(Q);
		printf("\n");
		printf("Out : %d\n", out);
		//printq(Q);
	}
	


}

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

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

相关文章

漫漫数学之旅017

文章目录 经典格言数学习题古今评注名人小传&#xff08;一&#xff09;亚当斯密&#xff08;二&#xff09;J理查德高特三世 经典格言 科学是热情与迷信之毒的最佳解毒剂。——亚当斯密&#xff08;Adam Smith&#xff09; 咳咳&#xff0c;各位看官&#xff0c;且听我用轻松…

leetcode:买卖股票最佳时机二

思路&#xff1a; 使用贪心算法&#xff1a;局部最优是将买卖过程中产生的正数进行相加&#xff0c;进而使得最后结果最大&#xff08;全局最优&#xff09;。 price [7,1,5,10,3,6,4] -6,4,5,-7,3,-2 正数相加就得到了最大 代码实现&#xff1a; 1.循环中下标从1开始 …

文件包含知识点详细总结

如果想看图片和观感更好的话,可以直接去我的github或者gitbook github:https://github.com/kakaandhanhan/cybersecurity_knowledge_book-gitbook.22kaka.fun gitbook:http://22kaka.fun description: 这里将通过参考文章和做题一起进行总结,并且文件包含漏洞,很多都利用了…

CVE-2022-25487 漏洞复现

漏洞描述&#xff1a;Atom CMS 2.0版本存在远程代码执行漏洞&#xff0c;该漏洞源于/admin/uploads.php 未能正确过滤构造代码段的特殊元素。攻击者可利用该漏洞导致任意代码执行。 其实这就是一个文件上传漏洞罢了。。。。 打开之后&#xff0c;/home路由是个空白 信息搜集&…

常见的单片机及其功能

在当今电子技术快速发展的时代&#xff0c;单片机作为核心组件&#xff0c;在各类电子项目和产品中扮演着至关重要的角色。它们的应用范围从简单的家用电器控制到复杂的工业自动化系统&#xff0c;几乎无处不在。接下来&#xff0c;我们将以轻松的语言&#xff0c;探讨几种广泛…

InternLM大模型实战-3.InternLM+Langchain搭建知识库

文章目录 前言笔记正文大模型开发范式RAGFinetune LangChain简介构建向量数据库搭建知识库助手1 InternLMLangchain2 构建检索问答链3 优化建议 Web Demo 部署搭建知识库 前言 本文是对于InternLM全链路开源体系系列课程的学习笔记。【基于 InternLM 和 LangChain 搭建你的知识…

RS232、RS485 和 DB9 接口详解

简介&#xff1a; 本文介绍了 RS232 和 RS485 两种串行通信协议的物理层标准&#xff0c;以及它们与 DB9 接口的连接方式。此外&#xff0c;还介绍了 RS485 接口的全双工和半双工模式&#xff0c;以及它们的应用场景。 1. DB9 接口 DB9 接口是一种常见的 D 型连接器&#xff…

C#在窗体正中输出文字以及输出文字的画刷使用

为了在窗体正中输出文字&#xff0c;需要获得输出文字区域的宽和高&#xff0c;这使用MeasureString方法&#xff0c;方法返回值为Size类型&#xff1b; 然后计算输出的起点的x和y坐标&#xff0c;就可以输出了&#xff1b; using System; using System.Collections.Generic; …

springboot180基于spring boot的医院挂号就诊系统

医院挂号就诊系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装医院挂号就诊系统软件来发挥其…

限制资源使用

限制资源使用 您需要显示对服务器资源的访问来保护Web应用程序和应用程序数据不受未授权用户的访问。在Java EE Web应用程序中,您可以通过在应用服务器中创建用户和用户组来保护资源免受未经授权的访问。您可以为应用程序定义角色并在部署过程中将角色分配给用户。 1. 创建授权…

MacOS - 菜单栏上显示『音量』

教程步骤 点击打开系统偏好『设置』&#xff0c;并找到『控制中心』 在『控制中心模块』找到『声音』&#xff0c;选择『始终在菜单栏显示』

华为环网双机接入IPTV网络部署案例

环网双机接入IPTV网络部署案例 组网图形 图2 环网双机场景IPTV基本组网图 方案简介配置注意事项组网需求数据规划配置思路操作步骤配置文件 方案简介 随着IPTV业务的迅速发展&#xff0c;IPTV平台承载的用户也越来越多&#xff0c;用户对IPTV直播业务的可靠性要求越来越高。…

数据库管理-第149期 Oracle Vector DB AI-01(20240210)

数据库管理149期 2024-02-10 数据库管理-第149期 Oracle Vector DB & AI-01&#xff08;20240210&#xff09;1 机器学习2 向量3 向量嵌入4 向量检索5 向量数据库5 专用向量数据库的问题总结 数据库管理-第149期 Oracle Vector DB & AI-01&#xff08;20240210&#xf…

PHP特性知识点总结

如果想观感更好看到图片,可以去我的gitbook或者github去看 github:https://github.com/kakaandhanhan/cybersecurity_knowledge_book-gitbook.22kaka.fun gitbook:http://22kaka.fun description: 专门出的关于php的特性比较,后面好像也有java的特性。 🏀 PHP特性知识点…

Centos7离线安装MySQL5.7

卸载mariadb rpm -e --nodeps mariadb-libs可以使用rpm -qa|grep mariadb命令检测是否卸载完成。 关闭selinux 将/etc/selinux/config文件中的SELINUX设置为disabled下载MySql的相关rpm包 打开https://dev.mysql.com/downloads/mysql/ 选择Red Hat Enterprise Linux / Oracle L…

MySQL-索引(INDEX)

文章目录 1. 索引概述及优劣势2. 索引结构和不同引擎对索引的支持情况2.1 Btree2.2 Hash索引 3. 索引分类4. 索引语法5. 索引在什么情况下会失效&#xff1f;5.1 最左前缀法则5.2 范围查询5.3 索引列运算5.4 头部模糊查询5.5 OR连接条件5.6 字符串不加引号5.7 数据分布影响 6. …

《统计学简易速速上手小册》第8章:贝叶斯统计(2024 最新版)

文章目录 8.1 贝叶斯理论基础8.1.1 基础知识8.1.2 主要案例&#xff1a;疾病诊断8.1.3 拓展案例 1&#xff1a;垃圾邮件过滤8.1.4 拓展案例 2&#xff1a;财经新闻对股价的影响 8.2 贝叶斯方法的应用8.2.1 基础知识8.2.2 主要案例&#xff1a;个性化推荐系统8.2.3 拓展案例 1&a…

docker安装、运行

1、安装 之前有docker的话&#xff0c;需要先卸载旧版本&#xff1a; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 安装之前需要安装yum工具&#xff1a; sud…

数据结构:并查集讲解

并查集 1.并查集原理2.并查集实现3.并查集应用4.并查集的路径压缩 1.并查集原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中…

详细分析Redis中数值乱码的根本原因以及解决方式

目录 前言1. 问题所示2. 原理分析3. 拓展 前言 对于这方面的相关知识推荐阅读&#xff1a; Redis框架从入门到学精&#xff08;全&#xff09;Java关于RedisTemplate的使用分析 附代码java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; …