【数据结构】 队列详解!庖丁解牛般细致讲解!

这篇具有很好参考价值的文章主要介绍了【数据结构】 队列详解!庖丁解牛般细致讲解!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构】 队列详解!庖丁解牛般细致讲解!,数据结构探索,数据结构,c语言,开发语言

🎥 屿小夏 : 个人主页
🔥个人专栏 : 数据结构解析
🌄 莫道桑榆晚,为霞尚满天!

📑前言

什么是队列?队列有什么样的特性?它的应用场景有哪些?
本文会对队列这种数据结构进行进行庖丁解牛般的讲解,让你彻底学会数据结构!

🌤️队列的概念剖析

☁️什么是队列

队列是一种常见的数据结构,它按照先进先出(FIFO)的原则进行操作。队列中的元素按照进入的顺序排列,新元素插入到队列的一端,称为队尾,已有元素的删除操作则发生在队列的另一端,称为队头。

☁️队列的特性

  1. 先进先出(FIFO):队列中的元素按照进入的顺序排列,最先进入的元素最先被删除。
  2. 只能在队尾插入元素:新元素只能从队尾插入。
  3. 只能在队头删除元素:已有元素只能从队头删除。
  4. 队列长度可变:队列的长度可以根据需要动态变化。
  5. 队列可以为空:队列中没有元素时为空队列。
  6. 队列可以为满:队列中的元素数量达到了队列的最大容量时为满队列。

☁️队列的图解

【数据结构】 队列详解!庖丁解牛般细致讲解!,数据结构探索,数据结构,c语言,开发语言

这个可以简单理解成,就像是我们生活中的食堂打饭排队一样,先来的在前面后来的在后面,前面的打完饭后就走了。这就像是数据结构中的队列。

🌤️队列的详细实现

☁️队列不同的实现方式

  1. 数组实现:使用数组来存储队列中的元素,通过两个指针分别指向队头和队尾。入队操作时,将新元素插入到队尾,同时移动队尾指针;出队操作时,删除队头元素,同时移动队头指针。这种实现方式简单直观,但在动态扩容时需要进行数据的搬移,效率较低。
  2. 链表实现:使用链表来存储队列中的元素,每个节点包含一个元素和一个指向下一个节点的指针。入队操作时,创建一个新节点并插入到链表的末尾;出队操作时,删除链表的头节点。这种实现方式不需要进行数据的搬移,但需要额外的空间来存储指针。

本文我们的队列使用链表的形式来进行队列的实现。这里更推荐链表实现起来不会那么复杂。

【数据结构】 队列详解!庖丁解牛般细致讲解!,数据结构探索,数据结构,c语言,开发语言

☁️队列结构体

typedef int QDatatype;
 
typedef struct Qlistnode
{
	struct Qlistnode* next;
	QDatatype data;
}Qlistnode;
 
typedef struct Queue
{
	Qlistnode* fornt;
	Qlistnode* rear;
	int size;
}Queue;

对数据类型进行重命名,这样以后需要更换其他数据类型使用的时候只需要更改这一个地方就可以了。

​ 这里有两个结构体,进行了嵌套。定义一个链表的结点,包含当前结点元素和指向下一个结点的指针。然后定义一个队列结构体,队列中两个结构体体指针分别代表队头和队尾,size是当前队列的有效元素个数。

​ 这样做的目的是,方便了队列的头删(出队列)和尾插(入队列),已经获取队列内的元素个数和队尾、队头的元素。

☁️队列的初始化

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

这里先将所以的指针都置空,size为0,因为是初始化所以队中无元素。

☁️入队列

在队列插入数据,要先开辟一个结点的空间,用来存放值和下一个结点的地址。这里要进行两种情况的判断:如果队头为空时,代表此时队列中无元素,那么队头和队尾指针指向同一块空间。当队头不为空时,就将队尾的指针指向新开辟的结点。插入新数据后,size的个数++。

【数据结构】 队列详解!庖丁解牛般细致讲解!,数据结构探索,数据结构,c语言,开发语言

void QueuePush(Queue* q, QDatatype x)
{
	assert(q);
 
	Qlistnode* newnode = (Qlistnode*)malloc(sizeof(Qlistnode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (q->rear == NULL)
	{
		q->fornt = q->rear = newnode;
	}
	else
	{
		q->rear->next = newnode;
		q->rear = newnode;
	}
	q->size++;
}

☁️出队列

在队头删除数据,此处和入队列一样,要进行两种情况的判断:

​ 如果队头和队尾指针同时指向一块空间时,此时队列中只有一个元素,所以释放队头或队尾指针都可,然后将队头和队尾指针置空,方便下一次进行插入数据(入队列)。

​ 队头和队尾指针不相等时,表名队列有最少一个以上的元素,创建一个临时结点用来存放队头指针下一个元素的地址,然后释放队头指针,再让队头指针指向下一个元素。

​ 出队列后,队列中的有效元素个数就少了一个,所以size也要进行–。

【数据结构】 队列详解!庖丁解牛般细致讲解!,数据结构探索,数据结构,c语言,开发语言

void QueuePop(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
 
	if (q->fornt == q->rear)
	{
		free(q->fornt);
		q->fornt = NULL;
		q->rear = NULL;
	}
	else
	{
		Qlistnode* newnode = q->fornt->next;
		free(q->fornt);
		q->fornt = newnode;
	}
	q->size--;
}

☁️获取对头元素

要获取元素前需要进行判空,如果队列是空,那么就会报错。

队头指针指向的就是队列的首元素地址,进行解引用就可以获取队头的元素。

QDatatype QueueFornt(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
 
	return q->fornt->data;
}

☁️获取队尾元素

要获取元素前需要进行判空,如果队列是空,那么就会报错。

队头指针指向的就是队尾的首元素地址,进行解引用就可以获取队尾的元素。

QDatatype QueueRear(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
 
	return q->rear->data;
}

☁️队列的判空

队列如果为空的情况下代表队头指针是空,此时队列无元素。

bool QueueEmpty(Queue* q)
{
	assert(q);
 
	return q->fornt ==  NULL;
}

☁️队列有效的元素个数

我们先前定义的size就是队列中有效元素的个数。

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

☁️队列的销毁

因为队列是链表实现的,所以这里的释放空间要写成循环,释放队列中每一个结点的空间。

创建临时指针,让newnode去迭代。最后队头和队尾指针都置空,size归0。

void QueueDestroy(Queue* q)
{
	assert(q);
 
	Qlistnode* newnode = q->fornt;
	while (newnode)
	{
		q->fornt = newnode->next;
		free(newnode);
		newnode = q->fornt;
	}
	q->fornt = q->rear = NULL;
	q->size = 0;
}

🌤️队列的应用场景

队列在计算机科学和软件开发中有广泛的应用场景:

  1. 任务调度:队列可以用来实现任务调度系统,将待执行的任务按照先后顺序排列,每次从队头取出一个任务进行执行,保证任务按照顺序执行。
  2. 消息传递:队列可以用来实现消息传递系统,消息发送方将消息入队,消息接收方从队头出队获取消息。这种方式可以实现异步消息传递,并且可以处理消息的积压情况。
  3. 缓冲区:队列可以用来实现缓冲区,例如网络数据传输中的数据包缓冲区、磁盘读写中的数据缓冲区等。数据可以按照顺序入队,然后按照顺序出队进行处理,保证数据的有序性和流畅性。
  4. 广度优先搜索:在图的广度优先搜索算法中,使用队列来存储待访问的节点,每次从队头取出一个节点进行访问,并将其邻接节点入队。这样可以保证按照层次遍历图的节点,从而实现广度优先搜索。
  5. 线程池:在多线程编程中,线程池可以使用队列来实现任务的调度。将待执行的任务入队,线程池中的线程从队头取出任务进行执行,保证任务的有序执行和线程的复用。

以上只是一些常见的应用场景,队列还可以用于解决其他问题,如数据流量控制、请求排队、打印队列等。队列的先进先出特性使其在这些场景下能够提供高效的数据处理和调度能力。

🌤️全篇总结

本篇对队列这种数据结构进行了概念的说明,对队列的实现细致入微,最后普及了队列这种数据结构的泛用性!

☁️ 好啦,由于篇幅有限,本章仅对队列进行了细致入微的讲解,后序还会有更多的数据结构文章分享哦!
看到这里了希望给博主留个:👍 点赞🌟收藏 ⭐️ 关注!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
【数据结构】 队列详解!庖丁解牛般细致讲解!,数据结构探索,数据结构,c语言,开发语言文章来源地址https://www.toymoban.com/news/detail-735638.html

到了这里,关于【数据结构】 队列详解!庖丁解牛般细致讲解!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 庖丁解牛函数知识---C语言《1》

    目录 前言: 1.程序中的函数 2.库函数的学习和使用 3.自定义函数 4.传值调用与传址调用 5.形参与实参 6.练习---二分查找函数 ❤博主CSDN:啊苏要学习   ▶专栏分类:C语言◀   C语言的学习,是为我们今后学习其它语言打好基础,C生万物!   开始我们的C语言之旅吧!✈   在计

    2024年02月02日
    浏览(53)
  • C生万物 | 操作符汇总大全【庖丁解牛,精细讲解】

    本篇博客全站热榜最高排名:2 因为MarkDown的语法,所以用图片的形式显示 对于算术操作符而言有上面这五种,对于前面的【+】、【-】、【*】来说操作数可以是整数或者浮点数 对于【/】来说,叫做 整除 ,结果就是我们在数学中说到的 商 。若是两边都是整数,则执行执行

    2023年04月08日
    浏览(52)
  • 【C++庖丁解牛】自平衡二叉搜索树--AVL树

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 前面对map/multimap/set/multiset进行了简单的介绍,在其文档介绍中发现,这几个容器有个共同点是:其底层都

    2024年04月09日
    浏览(97)
  • 【C++庖丁解牛】二叉搜索树(Binary Search Tree,BST)

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,

    2024年03月28日
    浏览(64)
  • 【C++庖丁解牛】vector容器的简易模拟实现(C++实现)(最后附源码)

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 我们前面介绍了vector容器的概念以及对其基本使用进行了介绍,如果你在这里不知道vector是什么以及不知

    2024年03月14日
    浏览(44)
  • 【C++庖丁解牛】C++内存管理 | new和delete的使用以及使用原理

    📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 我们先来看下面的一段代码和相关问题 选择题: 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)

    2024年03月09日
    浏览(55)
  • 【C++庖丁解牛】实现string容器的增删查改 | string容器的基本接口使用

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 函数名称 功能说明 push_back 在字符串后尾插字符c append 在字符串后追加一个字符串 operator+= (重点) 在字符

    2024年03月14日
    浏览(69)
  • 【C++庖丁解牛】STL之vector容器的介绍及使用 | vector迭代器的使用 | vector空间增长问题

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 vector的文档介绍 vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存

    2024年03月14日
    浏览(79)
  • 【C++庖丁解牛】面向对象的三大特性之一多态 | 抽象类 | 多态的原理 | 单继承和多继承关系中的虚函数表

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 需要声明的,本节课件中的代码及解释都是在vs2013下的x86程序中,涉及的指针都是4bytes。如果要其他平台

    2024年04月10日
    浏览(57)
  • 【数据结构】详解环形队列

    队列的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于队列的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包