初阶数据结构之队列

目录

写在前面的话:

一,什么是队列

1.1队列基本结构

1.2队列实现结构

二,基本功能实现

2.1创建队列

2.2初始化队列

2.3队尾入队列

2.4队首出队列

2.5获取队列头部和尾部元素

2.6获取队列中元素个数

2.7检测队列是否为空

2.8释放队列

三,总结


写在前面的话:

小伙伴们大家好啊!上篇文章我们提到了栈这种数据结构。那么我们知道,栈是属于先进后出的一种数据结构,那么本文将为大家带来的是另一种分格不同的先进先出的数据结构,队列。

一,什么是队列

1.1队列基本结构

一种线性表,支持一端插入,一端删除的特殊线性表。支持插入的那一端称为队尾,而支持删除的的另一端称为队头。如下图所示:

1.2队列实现结构

那么我们知道,对于队列这样的先进后出的结构,如果我们用顺序表实现,那么对于删除将会比较麻烦,因为顺序表如果是删除的话,则需要将后面的元素依次往前移动一位,这样就有一定的消耗了。

所以我们考虑用链表实现,链表的尾插和头删相对来说都是比较容易实现的。

二,基本功能实现

2.1创建队列

对于单链表来说,我们在创建的时候,需要一个 data 域以及一个next 指针域。

而对于对于我们将要实现的队列来说,因为需要操作队头以及队尾,所以我们直接将这两个指针定义出来,这样在用的时候,就不需要再去找了。

那么这里定义两层结构体之后, head 指针和 tail 指针分别表示头节点和尾节点。

2.2初始化队列

因为这里是有两个节点指针的,所以我们需要将两个指针都初始化为空。

 2.3队尾入队列

那么对于单链表来说,首先就是新增节点。

需要注意,这里的新增节点,其基本类型是 QueueNode ,而不是 Queue,因为 QueueNode 表示的才是单个的节点,而 Queue 表示的是两个节点指针的结构体。

其次,我们需要注意单链表的尾插是有链两个步骤的,因为这里我们没有新建一个不保存数据的头节点,所以在尾插的时候,首先是头插,然后才是尾插。

//队尾入队列
void QueuePush(Queue* pq, QNDateType x)
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	assert(newnode);
	newnode->data = x;
	newnode->next = NULL;

	if (pq->head == NULL)
	{
		pq->head =pq->tail= newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = pq->tail->next;
	}
}

而对于这里的尾插来说,因为是两层结构,所以是 pa->tail->next,移动的时候也是同样的

2.4队首出队列

那么同样的,因为我们没有开辟不存放数据的头节点,所以我们直接新建一个指针 cur 指向头节点的下一个节点,在将该头节点释放之后,再将头指针链接到 cur 即可。

2.5获取队列头部和尾部元素

因为在之前我们创建的时候就直接定义了一头一尾两个指针,所以如果需要获取队列头部和尾部元素,直接调用两个指针的 data 域即可。当然前提是,队列中有节点,我们采用暴力解法,断言解决。

2.6获取队列中元素个数

对于单链表,如果我们想计算节点个数,那么一般情况下,我们会用遍历去解决。

如下代码所示,首先定义一个计数器置为 0 ,然后将其放入循环中开始遍历,当节点为空时,返回上次计算的计数器,就是最后的节点数。

相信有些小伙伴们一定有疑惑,为什么这里我们没有用 assert 断言当前链表是否为空。因为这里我们用 while 循环就判断了,如果链表为空的时候,直接返回的是 0 ,说明当前链表为空。

2.7检测队列是否为空

对于这部分内容,我们已经很熟悉了,因为每一种数据结构都需要判断是否为空。同样的,我们也是用布尔值来返回。

2.8释放队列

这里我们通过两步实现队列的释放,首先我们需要通过一个循环释放队列中所有元素,其次我们需要做的就是将原先定义的两个指针置空,如果这两个指针不置空的话,会出现野指针问题。

那么对于具体的实现来说,还是需要一个指针记录当前节点的位置,然后依次释放。

三,总结

那么分析到这里我们对于队列基本功能的实现就了解完了。那么小伙伴们看了之后,是否有一定的启发呢?为什么我们会使用链表而不是顺序表实现?那么对于链表实现,不论是在队尾入元素,还是队头出元素,和之前先进后出的栈结构,有什么不同呢?

这些都值得我们深思。

好的,那么本文到此就结束啦,如果小伙伴有问题,还请指正呀!


版权声明:本文为qq_52777887原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。