带你深入了解队列(c/cpp双版本模拟实现)

目录

一.队列的概念及结构

二.队列的实现

2.1队列的结构

2.2初始化队列

2.3队尾入队列 

2.4队头出队列 

2.5获取队列头部元素 

2.6获取队列队尾元素

2.7获取队列中有效元素个数 

2.8检测队列是否为空

2.9销毁队列 

三.C++ 版本模拟实现队列


一.队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

二.队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

2.1队列的结构

首先,先建立一个单链表,用来存储数据和链接结构

然后建立队列,队列有俩个节点,一个指向队列的开始,一个指向结尾

size 用于存储队列长度

// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* _pNext;
QDataType _data;
}QNode;

// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
int size;
}Queue;

2.2初始化队列

队列的初始化,把队列的头尾都指向空,size设为0

void QueueInit(Queue* q)
{
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}

2.3队尾入队列 

1.首先,malloc一个节点cur

2.判断malloc是否开辟成功

3.给创建成功的节点进行赋值

4.判断如果队列为空,直接插入节点即可(使队列的头尾都指向这个节点)

5.如果不为空,使队列的尾的下一个位置指向新创建的节点在然后队列的尾指向这个节点

6.最后,数据加一size++

void QueuePush(Queue* q, QDataType data)
{
	QNode* cur = (QNode*)malloc(sizeof(QNode));
     
	if (cur == NULL)
	{
		perror("malloc ");
		exit(-1);
	}
	cur->data = data;
	cur->next = NULL;

	if (q->rear == NULL)
	{
		q->front = q->rear = cur;
	}
	else
	{
		q->rear->next = cur;
		q->rear = cur;
	}
	q->size++;
}

2.4队头出队列 

1.先判断队列是否只有为空,如果是,退出

2.如果队列只有一个数据,直接对队列进行销毁即可

3.如果队列有多个数据,新建一个节点cur等于队列“头”的下一个地址,然后释放掉队头,再把队头指向cur(以前对头的下一个地址),使得第二个数据成为队头

4.最后,数据减一size--

void QueuePop(Queue* q)
{
     if(q->front==NULL)
     {
      exit(-1);
     }
	if (q->front->next == NULL)
	{
		free(q->front);
		q->front = q->rear = NULL;
	}
	else
	{
		QNode* cur = q->front->next;
		free(q->front);
		q->front = cur;
	}
	q->size--;
}

2.5获取队列头部元素 

直接取头指向的数据即可

QDataType QueueFront(Queue* q)
{
	return q->front->data;
}

2.6获取队列队尾元素

直接取队列尾指向的元素即可

QDataType QueueBack(Queue* q)
{
	return q->rear->data;
}

2.7获取队列中有效元素个数 

直接返回队列的size

int QueueSize(Queue* q)
{
	return q->size;
}

2.8检测队列是否为空

检测队列是否为空,如果为空返回非零结果,如果非空返回0 

bool QueueEmpty(Queue* q)
{
	return q->front == NULL && q->rear == NULL;
}

2.9销毁队列 

1.采用while循环依次把队列中的节点全部释放

2.使队列头尾指向空,并且size置为0

void QueueDestroy(Queue* q)
{
	QNode* cur = q->front;
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
}

三.C++ 版本模拟实现队列
 

     考虑到学校有好多老师上课,虽然说得是用c语言实现,却用cpp进行操作,现在给大家更新cpp版本的队列的模拟实现,cpp版本的扩容使用的new,函数参数使用的&,可能有同学对指针使用不太熟悉,所以我们同意用&(引用)来实现,方便大家的理解,就不再详细的进行说明了,思路跟c语言实现的一样,只是c和cpp的语言差距有所不同。

#include<iostream>
#include<assert.h>
using namespace std;

typedef  int  QDataType;

typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* front;
	QNode* rear;
	int size;
}Queue;

// 初始化队列 
void QueueInit(Queue& q)
{
	
	q.front = NULL;
	q.rear = NULL;
	q.size = 0;
}
// 队尾入队列 
void QueuePush(Queue& q, QDataType data)
{
	QNode* cur = new QNode[sizeof(QNode)];

	if (cur == NULL)
	{
		perror("malloc ");
		exit(-1);
	}
	cur->data = data;
	cur->next = NULL;

	if (q.rear == NULL)
	{
		q.front = q.rear = cur;
	}
	else
	{
		q.rear->next = cur;
		q.rear = cur;
	}
	q.size++;
}
// 队头出队列 
void QueuePop(Queue& q)
{
	if (q.front->next == NULL)
	{
		delete q.front;
		q.front = q.rear = NULL;
	}
	else
	{
		QNode* cur = q.front->next;
		delete q.front;
		q.front = cur;
	}
	q.size--;
}
// 获取队列头部元素 
QDataType QueueFront(const Queue& q)
{
	return q.front->data;
}
// 获取队列队尾元素 
QDataType QueueBack(const Queue& q)
{
	return q.rear->data;
}
// 获取队列中有效元素个数 
int QueueSize(const Queue& q)
{
	return q.size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(const Queue& q)
{
	return q.front == NULL && q.rear == NULL;
}
// 销毁队列 
void QueueDestroy(Queue& q)
{
	QNode* cur = q.front;
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}

	q.front = NULL;
	q.rear = NULL;
	q.size = 0;
}

int main()
{
	Queue q;
	QueueInit(q);

	QueuePush(q, 1);
	QueuePush(q, 2);
	QueuePush(q, 3);
	for (int i = 0;i < 3;i++)
	{
		cout << QueueFront(q) << endl;
		QueuePop(q);
	}

	printf("%d", !QueueEmpty(q));

	QueueDestroy(q);
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于 C# 实现样式与数据分离的打印方案

对于八月份的印象&#xff0c;我发现大部分都留给了出差。而九月初出差回来&#xff0c;我便立马投入了新项目的研发工作。因此&#xff0c;无论是中秋节还是国庆节&#xff0c;在这一连串忙碌的日子里&#xff0c;无不充满着仓促的气息。王北洛说&#xff0c;“活着不就是仓促…

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin import android.os.Bundle import android.util.Log import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.b…

剑指JUC原理-4.共享资源和线程安全性

共享问题 小故事 老王&#xff08;操作系统&#xff09;有一个功能强大的算盘&#xff08;CPU&#xff09;&#xff0c;现在想把它租出去&#xff0c;赚一点外快 小南、小女&#xff08;线程&#xff09;来使用这个算盘来进行一些计算&#xff0c;并按照时间给老王支付费用 …

强化学习------PPO算法

目录 简介一、PPO原理1、由On-policy 转化为Off-policy2、Importance Sampling&#xff08;重要性采样&#xff09;3、off-policy下的梯度公式推导 二、PPO算法两种形式1、PPO-Penalty2、PPO-Clip 三、PPO算法实战四、参考 简介 PPO 算法之所以被提出&#xff0c;根本原因在于…

按照正规的软件开发流程,项目原型评审是全程对着页面评审吗

项目原型评审是软件开发过程中的一步&#xff0c;它的目的是确保设计和需求的一致性&#xff0c;以及提供一个可视化的界面供所有相关方进行沟通和理解。评审过程中&#xff0c;可能会涉及到多个方面&#xff1a; 用户界面&#xff08;UI&#xff09;&#xff1a;确保UI设计满足…

电脑如何激活windows

当我们电脑出现如下图&#xff1a; 显示需要激活windows时&#xff0c;操作如下。 1、桌面-新建-文本文档 2、将文档命名为&#xff08;激活windows.bat&#xff09;把原有文档中的后缀.txt去掉 3、点击右键&#xff0c;选择编辑输入代码 slmgr/skms kms.03k.org slmgr/ato4、…

Python----break关键字对while...else结构的影响

案例&#xff1a; 女朋友生气&#xff0c;要求道歉5遍&#xff1a;老婆大人&#xff0c;我错了。道歉到第三遍的时候&#xff0c;媳妇埋怨这一遍说的不真诚&#xff0c;是不是就是要退出循环了&#xff1f;这个退出有两种可能性&#xff1a; ① 更生气&#xff0c;不打算原谅…

c语言进制的转换8进制转换2进制

c语言进制的转换之8进制转换2进制与2转8 c语言的进制的转换 c语言进制的转换之8进制转换2进制与2转8一、八四二一法则二、八进制转换二进制方法三、八进制程序打印 一、八四二一法则 二、八进制转换二进制方法 如&#xff1a;3703转换为2进制 按照八四二一法则&#xff0c;分为…

创纪录的1亿RPS DDoS攻击利用HTTP/2快速重置漏洞

导语&#xff1a;最近&#xff0c;一项创纪录的DDoS攻击引起了广泛关注。攻击者利用了HTTP/2协议中的一个快速重置漏洞&#xff0c;发起了一系列超大规模的攻击。本文将为大家详细介绍这次攻击的背景、影响以及应对措施。 攻击背景 最近&#xff0c;全球范围内遭受了一系列规模…

Fabric.js 样式不更新怎么办?

本文简介 带尬猴&#xff0c;我嗨德育处主任 不知道你有没有遇到过在使用 Fabric.js 时无意中一些骚操作修改了元素的样式&#xff0c;但刷新画布却没更新元素样式&#xff1f; 如果你也遇到同样的问题的话&#xff0c;可以尝试使用本文的方法。 是否需要重新绘制 我先举个例…

【Javascript】ajax(阿甲克斯)

目录 什么是ajax? 同步与异步 原理 注意 写一个ajax请求 创建ajax对象 设置请求方式和地址 发送请求 设置响应HTTP请求状态变化的函数 什么是ajax? 是基于javascript的一种用于创建快速动态网页的技术&#xff0c;是一种在无需重新加载整个网页的情况下&#xff0c…

解决Visual studio 未能正确加载...包问题

问题 解决&#xff1a; 菜单: Visual Studio 2019 -> 输入"devenv /resetsettings " 将之前的设置恢复到原始状态。且可以正常使用。理论应该可以使用到其它版本中……

业务架构、应用架构、技术架构、数据架构

架构规划的重要性 如果没有进行合理的架构规划&#xff0c;将会引发一系列的问题。为了避免这些问题的发生&#xff0c;企业需要进行业务架构、应用架构、技术架构和数据架构的全面规划和设计&#xff0c;以构建一个清晰、可持续发展的企业架构。 https://www.zhihu.com/que…

CVE-2022-32991靶场复现

靶场环境&#xff1a; 题目提示了该CMS的welcome.php中存在SQL注入攻击。 CVE官方给出的提示&#xff1a; welcome.php页面存在SQL注入&#xff0c;并且这个参数是eid 打开靶场环境&#xff1a; 页面是一个登陆注册的界面 用户注册&#xff1a; 1 010.com 123456 123456 点击Re…

web - Tomcat服务器

文章目录 目录 文章目录 前言 一 . CS和BS的异同 二 . 什么是Tomcat 二 . Tomcat安装 四 . Tomcat目录结构 bin目录: 用于存放二进制的可执行文件 config目录 server.xml&#xff1a;配置整个服务器信息。例如修改端口号。默认HTTP请求的端口号是&#xff1a;8080 lib目录 log…

【电路笔记】-电路中的复数与相量(Phasor)

电路中的复数与相量(Phasor) 文章目录 电路中的复数与相量(Phasor)1、概述2、复数定义3、复数计算规则4、电子领域的复数5、总结 复数是一种重要的数学工具&#xff0c;广泛应用于包括电子学在内的许多物理领域。 这个概念可能看起来很奇怪&#xff0c;但它们的操作很简单&…

C++进阶语法——OOP(面向对象)【学习笔记(四)】

文章目录 1、C OOP⾯向对象开发1.1 类&#xff08;classes&#xff09;和对象&#xff08;objects&#xff09;1.2 public、private、protected访问权限1.3 实现成员⽅法1.4 构造函数&#xff08;constructor&#xff09;和 析构函数&#xff08;destructor&#xff09;1.4.1 构…

第四章 文件管理 八、文件保护

目录 一、口令保护 1、定义&#xff1a; 2、优点&#xff1a; 3、缺点: 二、加密保护 1、定义&#xff1a; 2、例子&#xff1a; 2、优点&#xff1a; 3、缺点: 三、访问控制 1、定义&#xff1a; 2、精简的访问控制表&#xff1a; &#xff08;1&#xff09;定义&a…

JS实现商品SKU

<!DOCTYPE html> <html> <head><title>商品SKU</title><link rel"stylesheet" href"element/css/element.css"><style>*{ margin:0; padding:0px; box-sizing: border-box; }ul,li{ list-style-type: none;}bod…

LVS集群-NAT模式

集群的概念&#xff1a; 集群&#xff1a;nginx四层和七层动静分离 集群标准意义上的概念&#xff1a;为解决特定问题将多个计算机组合起来形成一个单系统 集群的目的就是为了解决系统的性能瓶颈。 垂直扩展&#xff1a;向上扩展&#xff0c;增加单个机器的性能&#xff0c;…