数据结构--队列【详解】~(˶‾᷄ꈊ‾᷅˵)~

news2024/11/29 3:49:04

目录

队列定义:

 队列的声明与头文件的包含:

队列的声明: 

头文件的包含: 

队列的基本操作: 

初始化队列 : 

 摧毁队列:

 入队列:

 出队列:

返回队头数据:

返回队尾数据:

返回队列当前大小:

判空操作:

测试数据: 

最后,完整代码:


队列定义:

队列是一个先进先出的数据结构(First in First out)。只能对表尾进行插入,对表头进行结点的删除,这样强限制性的链表,这就是所说的队列。也就是说,队列是限定在表的一端进行插入,表的另一端进行删除的数据结构。

图解:

 如同日常生活中去买票排队,每一列队伍都有一个队尾和队首,先来的先买票,后来的后买,买好的就从队首出去,新来买票的就需要从队尾继续排队。

为了使用的方便,咱们将队头位置的指针命名为head,队尾为tail 

 队列的声明与头文件的包含:

队列的声明: 

typedef int QDataType;

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

typedef struct Queue//定义类型为QNode的指向队头和队尾的指针
{
	QNode* head;
	QNode* tail;
}Queue;

这里通过单链表实现队列,需要一个单链表的结构QueueNode。然后头尾指针需要另外开辟一个结构体,指针的类型是QNode*. 通过指针head和tail来查询队列中的队头和队尾数据。

头文件的包含: 

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

队列的基本操作: 

//初始化队列
void QueueInit(Queue* pq);
//摧毁队列
void QueueDestory(Queue* pq);

//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);
//返回队头数据
QDataType QueueFront(Queue* pq);
//返回队尾数据
QDataType QueueBack(Queue* pq);
//返回队列当前大小
int QueueSize(Queue* pq);
//判空操作
bool QueueEmpty(Queue* pq);

 

初始化队列 : 

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;//将指向队头和队尾的指针置空
}

 摧毁队列:

void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;//保存下一个节点的指针,释放当亲位置的空间
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;//释放完后将队头和队尾指针都置空
}

 入队列:

void QueuePush(Queue* pq,QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)//为新节点开辟空间
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;//为新节点赋值
	if (pq->tail == NULL)//若当前尾为空,就将队头,尾指针指向newnode
	{
		pq->tail = pq->head = newnode;
	}
	else
	{
		pq->tail->next = newnode;//否则队尾指针的next指向newnode
		pq->tail = newnode;
	}
}

1.入队列前需要开辟一个新节点,同时进行判空操作

2.进行入队操作的时候,首先需要判断队列是否为空,如果队列为空的话,需要将头指针和尾指针一同指向第一个结点 

3.如果不为空,就进行队列的尾插操作,同时移动tail的位置以便于下一次的插入

 

 出队列:

void QueuePop(Queue* pq)
{
	assert(pq);
	//一个
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	//多个
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

出队列是需要判断当前队列中的节点个数,分为一个和多个进行讨论。如果只有一个,就将头节点内存释放,接着将头尾指针置空,防止野指针的出现。如果是多个节点,就需要将头节点的下一个节点保存,以免找不到。接着将头节点内存释放,释放后,移动头指针head的位置,使其指向下一个节点。 

返回队头数据:

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}

返回队尾数据:

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->tail->data;
}

返回队列当前大小:

int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

判空操作:

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

测试数据: 

 

最后,完整代码:

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

typedef int QDataType;

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

typedef struct Queue//定义类型为QNode的指向队头和队尾的指针
{
	QNode* head;
	QNode* tail;
}Queue;
//初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;//将指向队头和队尾的指针置空
}
//摧毁队列
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;//保存下一个节点的指针,释放当亲位置的空间
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;//释放完后将队头和队尾指针都置空
}
//入队列
void QueuePush(Queue* pq,QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)//为新节点开辟空间
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;//为新节点赋值
	if (pq->tail == NULL)//若当前尾为空,就将队头,尾指针指向newnode
	{
		pq->tail = pq->head = newnode;
	}
	else
	{
		pq->tail->next = newnode;//否则队尾指针的next指向newnode
		pq->tail = newnode;
	}
}
//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	//一个
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	//多个
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
//返回队头数据
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}
//返回队尾数据
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->tail->data;
}
//返回队列当前大小
int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}
//判空操作
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

void QueueTest()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");
	QueueDestory(&q);
}
int main()
{
	QueueTest();
	return 0;
}

 博客到这里也是结束了,喜欢的小伙伴可以点赞加关注支持下博主,这对我真的很重要~~

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

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

相关文章

C#编程-使用变量

使用变量 请考虑以下场景:您必须创建一个程序,接受来自用户的两个数字并在屏幕上显示着两个数字之和。现在,读取用户提供的数字时,您需要将这些数字存储在内存中的某个位置,以便您能对这些数字执行加操作。您可以使用变量将这些数字存储在内存中。 下图显示了使用变量将…

乐观者成功,悲观者正确|2023年个人总结

上周一个好久没联系的朋友&#xff0c;突然微信问我&#xff1a;“土司&#xff0c;年终总结啥时候发出来&#xff0c;等着学习呢&#xff1f;”&#xff0c;听到这话既感动又愧疚&#xff0c;感动的是一个个人年终总结还被人惦记着&#xff0c;有一种稳稳的幸福&#xff1b;愧…

字符串与模拟法

加密英文 输入一个字符串可用getline(cin,数组名) 字典序 在字符串中寻找子字符串 分糖果 代码 猴子选大王 代码 如果n号猴子被选中&#xff0c;则使得n号的猴子变成false&#xff0c;未出局的猴子为true。 if(pn1) p1;这个是将超出的下标重新变回1号&#xff0c;使其重新循…

Selenium教程04:鼠标+键盘网页的模拟操作

在webdriver 中&#xff0c;鼠标操作都封装在ActionChains类中&#xff0c;使用的时候需要导入这个包。 from selenium.webdriver import ActionChainsActionChains方法列表如下&#xff1a; click(on_elementNone) ——单击鼠标左键click_and_hold(on_elementNone) ——点击…

webpack的深入学习与实战(持续更新)

一、何为Webpack Webpack是 一个开源的JavaScript模块打包工具&#xff0c;其最核心的功能是解决模块之间的依赖&#xff0c;把各个模块按照特定的规则和顺序组织在一起&#xff0c;最终合并为一个JS文件或多个。 二、带宽的换算 目前我们的云服务器带宽为5M 三 、bundle 体…

Java 动态树的实现思路分析

Java 动态树的实现 目录概述需求&#xff1a; 设计思路实现思路分析1. 简单Java实现&#xff1a;2.建立父子表存储3.前端的对应的json 字符串方式 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0…

【并发设计模式】聊聊Thread-Per-Message与Worker-Thread模式

在并发编程中&#xff0c;核心就是同步、互斥、分工。 同步是多个线程之间按照一定的顺序进行执行&#xff0c;比如A执行完&#xff0c;B在执行。而互斥是多个线程之间对于共享资源的互斥。两个侧重点不一样&#xff0c;同步关注的是执行顺序&#xff0c;互斥关注的是资源的排…

Django 学习教程- Hello world入门案例

系列 Django 学习教程-介绍与安装-CSDN博客 欢迎来到第Djagno学习教程第二章Hello World 入门案例。 在本教程中&#xff0c;我将引导您完成django的Hello World入门案例。 让我们开始吧&#xff01; 版本 Django 5.0Python 3.10 创建项目 安装 Django 之后&#xff0…

Linux 权限掌控术:深入探索和用户管理

文章目录 前言1.外壳程序是什么&#xff1f;外壳程为什么存在&#xff1f;工作原理外壳程序怎么个事&#xff1f; 2. Linux权限的概念2.1 什么是权限2.2权限的本质2.3 Linux中的用户 3. 普通用户变成rootlinux中有三种人 4.Linux中文件的权限4.1文件的属性权限4.2 掌握修改权限…

[DL]深度学习_AlexNet

AlexNet网络详解 目录 一、AlexNet 1、详细介绍 2、网络框架 二、网络详解 1、首次使用ReLu激活函数 2、模型基本结构与双GPU实现 3、局部响应归一化(LRN) 4、重叠池化(Overlapping Pooling) 5、数据增强 6、Dropout 一、AlexNet 1、详细介绍 AlexNet是一种经典的卷积…

Javascript 循环结构while do while for实例讲解

Javascript 循环结构while do while for实例讲解 目录 Javascript 循环结构while do while for实例讲解 一、while语句 二、do…while语句 三、for循环 疑难解答 我们从上一节课知道&#xff0c;JavaScript循环结构总有3种&#xff1a; &#xff08;1&#xff09;while语…

S7.Net与西门子PLC通讯

开发环境准备 同时由于设备还未采购,没有设备进行测试开发,会安装一个仿真模拟器进行调试。(真心的,谁想到还能仿真模拟设备) 需要安装的软件包括 ◦TIA Portal V14 ◦S7-PLCSIM V14 ◦NetToPLCsim-S7o-v-1-2-2-0 TIA Portal 西门子官方管理设备数据块的客户端,每一…

【网络安全】upload靶场pass11-17思路

目录 Pass-11 Pass-12 Pass-13 Pass-14 Pass-15 Pass-16 Pass-17 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &#x…

盾构机数据可视化监控平台 | 图扑数字孪生

2002 年,中国 863 计划把盾构机列为国家关键技术&#xff0c;以国家力量为主导&#xff0c;集中力量进行盾构机专项研究。在 2008 年&#xff0c;中国成功研制出属于自己的国产盾构机——中国中铁一号&#xff0c;同时还打通了天津地铁 1500m 的隧道。此举更彻底地打破了国内盾…

基于Java SSM框架实现企业销售人员培训系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现企业销售人员培训系统演示 摘要 目前由于我国企业销售人员培训系统的规模较小,同发达国家相比,人员培训比重始终偏低,用户意识比较低下,为进一步提高用户的销售意意识的提升,我觉得开发一套关于企业销售人员培训系统很人必要,虽然许多企业主动选用人员培…

测试新字符设备驱动代码

一. 简介 上一篇文章编写了新字符设备驱动框架的代码&#xff0c;并编写了 LED灯IO初始化工作&#xff0c;也编写了Led的开与关函数。文章地址如下&#xff1a; 向新字符设备驱动代码框架中添加Led功能函数-CSDN博客 本文对所完成的新字符设备驱动代码进行测试。通过测试程…

[电磁学]大学物理陈秉乾老师课程笔记

主页有博主其他上万字的精品笔记,都在不断完善ing~ 第一讲 绪论,库仑定律 主要讲解了电磁学中的库伦定律和电场的相关概念&#xff0c;介绍了电荷和电磁相互作用的规律&#xff0c;并讲解了电场强度和电势的概念。 03:14 &#x1f393; 库伦定律&#xff1a;电势能与电荷的关…

学习华为企业无线网络,有这篇文章就够了。

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; •以有线电缆或光纤作为传输介质的有线局域网应用广泛&#xff0c;但有线传输介质的铺设成本高&#xff0c;位置固定&#xff0c;移动性差。随着人们对…

智安网络|实现安全与网络功能一体化:SASE的全新安全策略

随着企业信息化和数字化程度的不断提升&#xff0c;网络安全面临着前所未有的挑战。传统的网络安全模式已经无法满足日益复杂的安全需求。在这一背景下&#xff0c;安全访问服务边缘&#xff08;SASE&#xff09;崭露头角&#xff0c;并逐渐成为新一代网络安全架构的关键概念。…

丢失VCRUNTIME140_1.dll怎么办,多种dll问题解决方法分享

丢失VCRUNTIME140_1.dll是许多计算机用户经常遇到的问题之一。VCRUNTIME140_1.dll是一个动态链接库文件&#xff0c;它是Visual C Redistributable Package的一部分。Visual C Redistributable Package是微软为了支持运行使用Visual C编写的软件而提供的一个可再发行组件包。当…