前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【初阶数据结构】深入解析队列:探索底层逻辑

【初阶数据结构】深入解析队列:探索底层逻辑

原创
作者头像
是店小二呀
发布2024-07-27 13:47:28
960
发布2024-07-27 13:47:28
举报
文章被收录于专栏:初阶数据结构

初阶数据结构

相关知识点

可以通过点击

以下链接进行学习

一起加油!

🔥引言

本篇将深入解析队列:探索底层逻辑,理解底层是如何实现并了解该接口实现的优缺点,以便于我们在编写程序灵活地使用该数据结构。

🌈个人主页: 是店小二呀

🌈C语言笔记专栏: C语言笔记

🌈C++笔记专栏: C++笔记

🌈初阶数据结构笔记专栏: 初阶数据结构笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅

一、队列的概念及结构

队列是指只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。队列具有先进先出 FIFO(First In First Out) 这一点跟栈的先进后出是相反的

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

队列可用通过数组或链表结构实现,一般推荐使用链表实现更优一点。如果使用数组实现在出队列时,需要挪移大量数据,效率较低

这里采用链表结构实现队列

在设计队列结构中,需要设计两个指针去控制队列各节点的情况。head(队头指针)指向实际对头元素,taill(队尾指针),指向实际队尾元素,增加一个变量size用于统计元素个数,由于存在多种信息,可以使用结构体统一管理

二、实现队列的相关接口(Stack.h)

2.1 队列初始化

代码语言:c
复制
void QueueInit(Queue *pq)//所以导致了需要初始化
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

这里需要注意的是:这里不需要对于节点进行初始化,在创建节点时会完成对应的初始化工作。

2.2 队尾入队列

代码语言:c
复制
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
	if (newnode == NULL)
	{
		perror("malloc fail!!!");
		return ;
	}
	//创建为需要初始化下
	newnode->next = NULL;
	newnode->val = x;
	if (pq->phead == NULL)
	pq->phead = pq->ptail = newnode;
	else
	{
		(pq->ptail)->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

这里需要注意的是:首先就是空间开辟失败,然后需要搞清楚我们申请空间是给谁使用的,这里是为节点开辟空间。而不是为Queue结构体对象开辟空间,这里节点之间连接是通过节点指针进行连接

2.3 队头出队列

代码语言:c
复制
void QueuePop(Queue* pq)
{
	assert(pq && pq->phead);

	Qnode *del = pq->phead;
	pq->phead = pq->phead->next;
	free(del);
	del == NULL;
	if (pq->phead == NULL)
	{
		pq->ptail = NULL;
	}
	pq->size--;
}

这里需要注意的是:当队列为空时,意味着头指针为空,那么尾指针也需要置成空

2.4 获得队列头部元素

代码语言:c
复制
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->val;
}

2.5 获得队列尾部元素

代码语言:c
复制
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->ptail->val;
}

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

代码语言:c
复制
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

2.7 检测队列是否为空

代码语言:c
复制
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL;
}

2.8 打印队列数据

代码语言:c
复制
void QueuePrint(Queue* pq)
{
	assert(pq);
	while (!QueueEmpty(pq))
	{
		printf("%d->", QueueFront(pq));
		QueuePop(pq);
	}
}

这里需要注意的是:这里不能用cur,因为cur是不会动的,phead在pop的时候一直移动

2.9 队列的销毁

代码语言:C
复制
void QueueDestroy(Queue* pq)
{
	assert(pq);
	Qnode* cur = pq->phead;
	while (cur)//删除的作用
	{
		Qnode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->ptail = NULL; pq->phead = NULL;
	pq->size = 0;
}

这里需要注意的是:这里cur不要手动置空,会跳出循环,需等待cur自动指向空

三、循环队列

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型 时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。(会单独一篇来讲述)


以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二初阶数据结构笔记,希望对你在学习初阶数据结构中有所帮助!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、队列的概念及结构
  • 二、实现队列的相关接口(Stack.h)
    • 2.1 队列初始化
      • 2.2 队尾入队列
        • 2.3 队头出队列
          • 2.4 获得队列头部元素
            • 2.5 获得队列尾部元素
              • 2.6 获取队列中有效元素个数
                • 2.7 检测队列是否为空
                  • 2.8 打印队列数据
                    • 2.9 队列的销毁
                    • 三、循环队列
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档