数据结构——队列

本文介绍了队列的基础结构,包括其先进先出(FIFO)特性、数据操作如初始化、销毁、入队、出队、获取元素个数和判断空队列的方法。此外,还讨论了队列在同步操作、动态扩容等方面的优势,以及容量限制、元素移动成本和检索效率低等劣势。
摘要由CSDN通过智能技术生成

目录

1.队列的基础结构

2.队列的数据操作

①队列的初始化

②队列的销毁

③队列入数据

④队列出数据

⑤取得队列元素个数

⑥判断队列内是否为空

⑦取得队列首元素

⑧取得队列尾元素

3.队列的优势与劣势


1.队列的基础结构

队列的结构特点如下

  1. 先进先出 (FIFO):队列是一种先进先出的数据结构,即最先进入队列的元素也会最先从队列中被取出。队列的头部保存的是最先进入的元素,而队列的尾部保存的是最后进入的元素。

  2. 只能在队列的两端进行操作:队列只允许在队列的头部删除元素,在队列的尾部添加元素。这种限制保证了队列的操作具有一定的顺序性,符合先进先出的规则。

  3. 支持动态扩容:队列可以通过动态扩容来适应不同的需求。当队列元素数量达到队列的容量上限时,队列会自动扩容,以容纳更多的元素。扩容操作可能会导致队列的头部和尾部的物理位置发生变化。

  4. 队列的容量有限:队列的容量是有限的,即队列能够容纳的元素数量是有限的。队列容量的大小通常在创建队列时就确定了,并且在队列使用过程中不会发生变化。如果队列已满,再次插入元素会导致队列溢出。

  5. 可以用数组或链表实现:队列可以用数组或链表来实现。使用数组实现的队列叫做顺序队列,使用链表实现的队列叫做链式队列。顺序队列和链式队列在底层数据结构和操作方式上有所不同,但它们都具有队列的基本特点。

在这里,我选择使用单链表来实现队列,定义队列的结构如下

typedef int QDatatype;

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

typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

2.队列的数据操作

①队列的初始化

//初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

②队列的销毁

//销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* tmp = cur->next;
		free(cur);
		cur = tmp;
	}

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

③队列入数据

//队列入数据
void QueuePush(Queue* pq, QDatatype x)
{
	assert(pq);

	QNode* tmp = (QNode*)malloc(sizeof(QNode));
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}

	tmp->data = x;
	tmp->next = NULL;

	if (pq->head == NULL)
	{
		assert(pq->tail);

		pq->head = pq->tail = tmp;
	}
	else
	{
		pq->tail->next = tmp;
		pq->tail = tmp;
	}

	pq->size++;
}

④队列出数据

//队列出数据
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->tail);

	QNode* tmp = pq->head;
	pq->head = pq->head->next;
	free(tmp);

	pq->size--;
}

⑤取得队列元素个数

//队列元素个数
int QueueSize(Queue* pq)
{
	assert(pq);

	/*int count = 0;
	QNode* cur = pq->head;

	while (cur)
	{
		count++;
		cur = cur->next;
	}

	return count;*/

	return pq->size;
}

⑥判断队列内是否为空

//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	/*if (pq->head == NULL)
	{
		return true;
	}
	else
	{
		return false;
	}*/

	return pq->size == 0;
}

⑦取得队列首元素

//取得队列首元素
QDatatype QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

⑧取得队列尾元素

//取得队列尾元素
QDatatype QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

3.队列的优势与劣势

①优势

  1. 先进先出:队列是一种先进先出的数据结构,它保证了元素的顺序性,符合实际问题的要求。例如,操作系统中的进程调度、消息队列等都需要保证先进入的元素先被处理。

  2. 轻松实现同步:队列可以很方便地实现同步操作。例如,多线程环境下,线程可以将任务添加到队列中,另一个线程负责从队列中取出任务并执行,从而避免了线程之间的竞争和死锁等问题。

  3. 支持动态扩容:队列可以通过动态扩容来适应不同的需求。当队列元素数量达到队列的容量上限时,队列会自动扩容,以容纳更多的元素。

  4. 适用于广泛的应用场景:队列可以用于广泛的应用场景,如进程调度、消息队列、网络数据包的传输等。

②劣势

  1. 队列的插入和删除操作的时间复杂度都为O(1),但在使用数组实现的队列中,插入和删除操作可能会导致元素的移动,造成额外的时间和空间开销。

  2. 队列容量有限:队列的容量是有限的,即队列能够容纳的元素数量是有限的。如果队列已满,再次插入元素会导致队列溢出。

  3. 队列的检索操作效率较低:在使用数组实现的队列中,查找队列中某个元素的效率较低,需要遍历整个队列来查找。

  4. 队列的数据存储必须是顺序的:队列只能在队列的头部删除元素,在队列的尾部添加元素,数据的存储必须是顺序的,不适合随机访问和修改数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值