队列

41 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情


什么是队列

队列也是一种特殊的线性结构。它只允许在一端进行插入数据,在另一端删除数据。插入数据叫做入队列,删除数据叫做出队列。在队尾插数据,在队头删数据。

实现队列

我们可以用类似链表的结构实现它。每个节点都包括一个数据,以及下一个节点的地址。由于队列的特殊性质(头删,尾插),所以我们包装两个指针,一个指针指向队头,一个指针指向队尾。 在这里插入图片描述

创建类型

节点类型

typedef int QueueTypeDate;

typedef struct QListNode
{
	struct QListNode* next;
	QueueTypeDate val;
}QNode;

由两个指针维护的队列 因为指针指向的是队列的节点,所以它的类型为节点指针的类型 即QNode*

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

初始化队列

置为空即可

void QueueInit(Queue* q)
{
	assert(q);
	q->head = q->tail = NULL;
}

队列是否为空

bool QueueEmpty(Queue* q)
{
	assert(q);

	return q->head == NULL;
}

入队列

入队列是从队列的尾进行插入的。 入队列的时候要判断队列是否为空,当为空的时候,头就要变。

void QueuePush(Queue* q, QueueTypeDate x)
{
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	newnode->next = NULL;
	newnode->val = x;

	if (QueueEmpty(q))
		q->head = q->tail = newnode;
	else
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}
}

出队列

出队列是从队头进行出数据的。 要注意两点 1.队列为空的时候不能进行出队操作 2.当队列中只有一个数据的时候,不能只改变队列的头,其队列的尾也要同时改变。

void QueuePop(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	if (q->head == q->tail)
	{
		free(q->head);
		q->head = q->tail = NULL;
	}
	else
	{
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	
}

队列的销毁

销毁的过程就是不断出队列的过程

void QueueDestroy(Queue* q)
{
	assert(q);
	while (q->head)
	{
		QueuePop(q);
	}
}

获得队头的数据

首先保证队列不能为空

QueueTypeDate QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->head->val;
}

获得队尾的数据

首先保证队列不能为空

QueueTypeDate QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->tail->val;
}

队列中的数据的个数

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