数据结构——关于队列

news2024/11/17 1:28:35

1.队列的概念及结构


队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特性

入队列:进行插入操作的一端称为队尾            出队列:进行删除操作的一端称为队头


2.队列的实现


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

这里是使用单链表实现,进行尾插头删


Queue.h 


#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;//下一个
	QDataType val;//当前节点的值
}QNode;


// 队尾插入
//void QueuePush(QNode** pphead, QNode** pptail, QDataType x);
// 队头删除
//void QueuePop(QNode** pphead, QNode** pptail);

//为了避免上面那样定义多个参数和二级指针,所以创建下面的结构体
typedef struct Queue
{
	QNode* phead;//头指针
	QNode* ptail;//尾指针
	int size;
}Queue;

//初始化
void QueueInit(Queue* pq);

//销毁
void QueueDestroy(Queue* pq);

// 队尾插入
void QueuePush(Queue* pq, QDataType x);

// 队头删除
void QueuePop(Queue* pq);

// 取队头的数据
QDataType QueueFront(Queue* pq);

//取队尾的数据
QDataType QueueBack(Queue* pq);

// 获取队列中有效元素个数
int QueueSize(Queue* pq);

//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);

 队尾插入
//void QueuePush(QNode** pphead, QNode** pptail, QDataType x);
 队头删除
//void QueuePop(QNode** pphead, QNode** pptail);

 

// 队尾插入
void QueuePush(QNode** pphead, QNode** pptail, QDataType x);

// 队头删除
void QueuePop(QNode** pphead, QNode** pptail);

如果出现上面那样需要定义多个参数和二级指针,可以创建下面的结构体

//如果出现需要定义多个参数和二级指针,可以创建下面的结构体
typedef struct Queue
{
	QNode* phead;//头指针
	QNode* ptail;//尾指针
	int size;
}Queue;

 


Queue.c

初始化

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

销毁

//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	//cur 当前节点
	QNode* cur = pq->phead;
	while (cur)
	{
		//保存下一个节点位置
		QNode* next = cur->next;
		free(cur);//释放当前节点

		cur = next;//指向下一个节点
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

队尾插入 

// 队尾插入
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	//如果malloc失败
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->next = NULL;
	newnode->val = x;//因为现在要尾插的是x

	//如果ptail为NULL,说明一个节点都没有
	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		//把新节点变成新的尾节点
		pq->ptail = newnode;
	}
	//如果不加size++那么实现QueueSize时就需要遍历
	pq->size++;
}

 

队头删除

// 队头删除
void QueuePop(Queue* pq)
{
	assert(pq);
	//判断有没有节点
	assert(pq->size != 0);

	//只有一个节点
	//phead的下一个节点为空
	if (pq->phead->next == NULL)
	{
		free(pq->phead);//释放头节点指向的“节点”

		//将头节点和尾节点只为NULL
		pq->phead = pq->ptail = NULL;
	}
	else // 多个节点
	{
		//先保存头节点的下一个节点的位置
		QNode* next = pq->phead->next;
		free(pq->phead);//释放头节点指向的“节点”
		pq->phead = next;//再指向下一个节点的位置
	}

	pq->size--;
}

取队头的数据

// 取队头的数据
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	//head为空没有数据取
	assert(pq->phead);

	return pq->phead->val;
}

 取队尾的数据

//取队尾的数据
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	//ptail为空没有数据取
	assert(pq->ptail);

	return pq->ptail->val;
}

获取队列中有效元素个数

// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

检查是否为空

//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
}


3. 完整代码

#include"Queue.h"

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	//cur 当前节点
	QNode* cur = pq->phead;
	while (cur)
	{
		//保存下一个节点位置
		QNode* next = cur->next;
		free(cur);//释放当前节点

		cur = next;//指向下一个节点
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

// 队尾插入
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	//如果malloc失败
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->next = NULL;
	newnode->val = x;//因为现在要尾插的是x

	//如果ptail为NULL,说明一个节点都没有
	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		//把新节点变成新的尾节点
		pq->ptail = newnode;
	}
	//如果不加size++那么实现QueueSize时就需要遍历
	pq->size++;
}

// 队头删除
void QueuePop(Queue* pq)
{
	assert(pq);
	//判断有没有节点
	assert(pq->size != 0);

	//只有一个节点
	//phead的下一个节点为空
	if (pq->phead->next == NULL)
	{
		free(pq->phead);//释放头节点指向的“节点”

		//将头节点和尾节点只为NULL
		pq->phead = pq->ptail = NULL;
	}
	else // 多个节点
	{
		//先保存头节点的下一个节点的位置
		QNode* next = pq->phead->next;
		free(pq->phead);//释放头节点指向的“节点”
		pq->phead = next;//再指向下一个节点的位置
	}

	pq->size--;
}

// 取队头的数据
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	//head为空没有数据取
	assert(pq->phead);

	return pq->phead->val;
}

//取队尾的数据
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	//ptail为空没有数据取
	assert(pq->ptail);

	return pq->ptail->val;
}

// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
}

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

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

相关文章

HiveSQL实战——大厂面试真题

一、字节跳动 最高峰同时直播人数 https://blog.csdn.net/SHWAITME/article/details/135918264 0 问题描述 有如下数据记录直播平台主播上播及下播时间&#xff0c;根据该数据计算出平台最高峰同时直播人数。 ------------------------------------------------------ | us…

NC 用两个栈实现队列

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 用两个栈来实…

计算最简比

原理 c 质数数组长度&#xff0c;除不了就c--&#xff0c;都除不了c0&#xff0c;while(0)退出循环。 mainwindow.h struct WbiH {int width;int height; };WbiH calcWbiH(int w, int h); mainwindow.cpp {......int width player->metaData(SLMD.at(i)).toSize().wi…

JVM上篇:内存与垃圾-回收篇05-本地方法接口和本地方法栈

笔记来源&#xff1a;尚硅谷 JVM 全套教程&#xff0c;百万播放&#xff0c;全网巅峰&#xff08;宋红康详解 java 虚拟机&#xff09; 文章目录 5. 本地方法接口和本地方法栈5.1. 什么是本地方法&#xff1f;5.2. 为什么使用 Native Method&#xff1f;5.2. 本地方法栈 5. 本地…

uniapp去掉页面导航条

在pages.json文件中&#xff0c;globalStyle中添加 ”app-plus“:{"titleNView":false }

C++ 常用STL底层原理

STL 1. std::vector 底层原理&#xff1a;std::vector 是一个动态数组。它在内存中分配一块连续的存储空间来存储元素。随着元素数量的增加&#xff0c;如果存储空间不够用&#xff0c;vector 会分配一块更大的内存&#xff0c;并将现有元素复制到新内存块中。通常&#xff0c…

JavaScript模块化——JS模块化介绍与CommonJS规范

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;vscode Chrome浏览器 目录 1.模块化概述 1.1什么是模块化 1.2为什么需要模块化 1.2.1全局污染 1.2.2依赖混乱 1.2.3数据安全 2.有哪些模块化规范 3.导入与导出 3.1导入 3.…

YOLOV5单目测距+车辆检测+车道线检测+行人检测(教程-代码)

YOLOv5是一种高效的目标检测算法&#xff0c;结合其在单目测距、车辆检测、车道线检测和行人检测等领域的应用&#xff0c;可以实现多个重要任务的精确识别和定位。 首先&#xff0c;YOLOv5可以用于单目测距。 通过分析图像中的目标位置和尺寸信息&#xff0c;结合相机参数和几…

React原理之Fiber详解

前置文章&#xff1a; React原理之 React 整体架构解读React原理之整体渲染流程 -----读懂这一篇需要对 React 整体架构和渲染流程有大致的概念 &#x1f60a;----- 在React原理之 React 整体架构解读中&#xff0c;简单介绍了 Fiber 架构&#xff0c;也了解了 Fiber 节点的…

一个云端应用市场和配套的移动办公APP,支持iOS和Android端,可私有部署,支持在线体验(附源码)

前言 在当前的企业应用市场中&#xff0c;许多移动办公软件不仅成-本高昂&#xff0c;而且在功能对接和接口完整性方面存在不足&#xff0c;导致开发成本居高不下。这促使企业和开发者寻求更加经济、高效且功能丰富的处理方案。 介绍 O2OA&#xff08;翱途&#xff09;开发平…

【15】大数据题目等

目录 一.大数据题目的解题技巧​编辑 二.找重复的URL 三.利用小内存找出所有出现两次的数。 四.位运算题目 五.面试原题 六,.判断一个32位正数是不是2的幂&#xff0c;4的幂 七.位运算实现加减乘除 加法 减法 乘法 除法 一.大数据题目的解题技巧 二.找重复的URL 方法…

uni-app--》打造个性化壁纸预览应用平台(一)

&#x1f3d9;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名前端工程师 &#x1f304;个人主页&#xff1a;亦世凡华、 &#x1f306;系列专栏&#xff1a;uni-app &#x1f307;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

linux更换为阿里云的yum下载镜像源

更换镜像源 1.备份&#xff1a; sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2.创建一个文件: cd /etc/yum.repos.d/ touch CentOS-Base.repo 3.往CentOS-Base.repo添加内容 vi CentOS-Base.repo 添加以下内容&#xff1a; [base…

vue3 组合式 API:setup()

查看vue3官网介绍&#xff1a;组合式 API&#xff1a;setup() 在 Vue 3 中&#xff0c;组合式 API 的 setup() 函数是一个非常重要的特性&#xff0c;它提供了一种更灵活和可维护的方式来组织组件的逻辑。 基本概念 setup() 函数是在组件实例创建之前执行的&#xff0c;它用于…

重复玩一个游戏就是自闭症吗?自闭的特征有哪些?

重复玩一个游戏并不一定是自闭症的标志。儿童在成长过程中&#xff0c;有时会因为对某个游戏或活动的喜爱而反复进行&#xff0c;这是他们探索世界、发展兴趣和技能的一种方式。然而&#xff0c;如果这种行为伴随着其他自闭症的典型特征&#xff0c;如语言障碍、社交障碍和兴趣…

C语言 ——— 修改默认对齐数以及结构传参

目录 前言 修改默认对齐数 结构体传参 前言 在上一篇中&#xff0c;有讲解到结构体内存对齐的规则以及默认对齐数 C语言 ——— 结构体内存对齐-CSDN博客 修改默认对齐数 修改默认对齐数所需要的宏命令&#xff1a;#pragma 代码演示&#xff1a; #pragma pack(1) // 将默…

MVCC工作原理深入解析

一、事务概述 mysql事务是指一组命令操作&#xff0c;在执行过程中用来保证要么全部成功&#xff0c;要么全部失败。事务是由引擎层面来支持的&#xff0c;MyISM引擎不支持事务&#xff0c;InnoDB引擎支持事务。 事务具有ACID四大特性 原子性&#xff08;Atomicity&#xff0…

XSS靶场(1-11关)

目录 简述xss xss第1关 xss第2关 ​编辑 xss第3关 xss第4关 xss第5关过滤了 on script xss第6关 xss第7关 xss第8关 xss第9关 xss第10关 xss11关 我把源代码靶场放到了最顶端 简述xss XSS攻击通常指的是通过利用网页开发时留下的漏洞&#xff0c;通过巧妙的方法…

【数据结构与算法 | 图篇】最小生成树之Prim算法

1. 前言 普里姆算法&#xff08;Prims Algorithm&#xff09;是一种用于寻找加权无向图中的最小生成树&#xff08;Minimum Spanning Tree, MST&#xff09;的贪心算法。 最小生成树是指对于一个给定的无向图&#xff0c;连接所有顶点且边的总权重最小的生成树。 2. 算法步骤 …

Spring Boot 核心配置

一、 Spring Boot配置文件分类 SpringBoot是基于约定的&#xff0c;所以很多配置都有默认值&#xff0c;但如果想使用自己的配置替换默认配置的话&#xff0c;就可以使用application.properties或者application.yml&#xff08;application.yaml&#xff09;进行配置 applicat…