[C语言数据结构]队列

目录

1.队列

1.1队列的概念及结构

2.队列的实现

2.1队列的实现

2.1.1声明

2.1.2初始化

2.1.3队列的销毁

2.1.4入队列

2.1.5出队列

2.1.6返回队列的首元素

2.1.7判断队列是否为空

2.1.8计算队列中元素的数量

int QueueSize(Queue* pq);

完整代码:

Quene.h:

Quene.c:


1.队列

1.1队列的概念及结构

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。即:先进先出

2.队列的实现

首先我们可以讨论一下,用数组实现好还是用队列实现好一些;

对于队列我们要进行入队和出队的操作,如果是使用数组来实现的话,那么我们所需要的时间开销就很大,需要不停的挪动数据。

但是反过来看链表的话,就方便了许多,不需要频繁的挪动数据,入队出队时的操作都显得相对容易和快速。

所以接下来我们将采用单链表的方式来实现队列。

2.1队列的实现

2.1.1声明

对于队列来说,我们采用单链表的形式来实现队列所以我们声明结构的形式和单链表几乎一样。一个区别队列这个为了方便入列出列,用了两个指针,一个用来指向头节点,另一个来指向尾节点。还有一个正整型变量用来记录队列的大小;

代码:

typedef int QdataType;

typedef struct QueueNode
{
	QdataType data;
	struct QueueNode* next;

}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
	size_t size;
}Queue;

2.1.2初始化

void QueueInit(Queue* pq);

初始化也是非常的简单,就是将头指针和尾指针来置空,防止野指针的问题;

代码:

//队列的初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
	pq->size = 0;
}

2.1.3队列的销毁

void QueueDestroy(Queue* pq);

对于队列的销毁,和单链表的销毁大同小异,都是从头开始一次进行free,代码实现不难;

代码:

//队列的销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	while (cur != NULL)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}

2.1.4入队列

入队列的话我们直接时进行一个尾插,但是我们这里采用的是无头的单链表,所以在这里我们要先判断一下,队列中是否有元素,如果有元素的话我们将头和尾都指向新插入的节点;

如果不是的话那就直接进行一个尾插

void QueuePush(Queue* pq, QdataType x);
代码:

//入队列
void QueuePush(Queue* pq, QdataType x)
{
	assert(pq);
	QueueNode* NewNode = (QueueNode*)malloc(sizeof(QueueNode));
	NewNode->next = NULL;
	NewNode->data = x;
	if (pq->head == NULL)
	{
		pq->head = NewNode;
		pq->tail = NewNode;
	}
	else
	{
		pq->tail->next = NewNode;
		pq->tail = NewNode;
	}
}

2.1.5出队列

出队列的时候我们要注意一种情况就是是当队列中只剩一个节点的情况需要进行特殊的处理;因为剩余一个节点的时候我们和多个节点同样处理的话,就会产生尾节点是野指针的情况;

void QueuePop(Queue* pq);

代码:

//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	//剩余一个节点的情况
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueueNode* del = pq->head;
		pq->head = pq->head->next;
		free(del);
	}
}

2.1.6返回队列的首元素

这个函数没什么说的,唯一要注意的就是就要判断队列中是否还存在元素的情况,这个也可以非常的简单因为采用assert来判断就好了;

QdataType QueueFront(Queue* pq);

代码:

//返回队列的首元素
QdataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}

2.1.7判断队列是否为空

bool QueueEmpty(Queue* pq);

//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}

2.1.8计算队列中元素的数量

直接返回队列的size即可;相对于遍历整个队列的方法来说,效率更高;

int QueueSize(Queue* pq);

代码:

//队列的大小
int QueueSize(Queue* pq) 
{

	return pq->size;
}

完整代码:

Quene.h:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>


typedef int QdataType;

typedef struct QueueNode
{
	QdataType data;
	struct QueueNode* next;

}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
	size_t size;
}Queue;


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

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

//入队列
void QueuePush(Queue* pq, QdataType x);

//出队列
void QueuePop(Queue* pq);

//返回队列的首元素
QdataType QueueFront(Queue* pq);

//返回队列的尾部元素
QdataType QueueBack(Queue* pq);

//队列的大小
int QueueSize(Queue* pq);

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

Quene.c:

代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"

//队列的初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
	pq->size = 0;
}

//队列的销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	while (cur != NULL)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}

//入队列
void QueuePush(Queue* pq, QdataType x)
{
	assert(pq);
	QueueNode* NewNode = (QueueNode*)malloc(sizeof(QueueNode));
	NewNode->next = NULL;
	NewNode->data = x;
	if (pq->head == NULL)
	{
		pq->head = NewNode;
		pq->tail = NewNode;
	}
	else
	{
		pq->tail->next = NewNode;
		pq->tail = NewNode;
	}
	pq->size++;
}

//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	//剩余一个节点的情况
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueueNode* del = pq->head;
		pq->head = pq->head->next;
		free(del);
	}
	pq->size--;
}

//返回队列的首元素
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;
}

//队列的大小
int QueueSize(Queue* pq) 
{
	//assert(pq);
	//int n = 0;
	//QueueNode* cur = pq->head;
	//while (cur)
	//{
	//	n++;
	//	cur = cur->next;
	//}
	//return n;
	return pq->size;
}

//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}

以上就是队列的实现的所有内容了,希望可以帮到你!

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小米睡不醒.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值