(数据结构)队列的实现

发布于:2022-08-04 ⋅ 阅读:(434) ⋅ 点赞:(0)

今天船长计划用简单的方式向大家介绍数据结构中重要知识点——队列

目录

1.队列的概念及结构

2.队列的实现 

2.1 头文件的包含

2.2构造结构体

2.3定义相应的函数  

2.4实现相应的函数 

2.4.1 初始化函数

2.4.2 队尾入队列、队头出队列

 2.4.3获取队头元素、获取队尾元素

 2.4.4 验空函数

2.4.5获取队列中有效元素个数、销毁队列

 2.5测试检验

4.结语


1.队列的概念及结构

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特征;进行插入操作的一端称为队尾,进行删除操作的一端称为队头;

下面我将向大家展示队列的结构图解:


2.队列的实现 

队列也可以数组和链表的结构实现,使用链表的结构实现更优,因为如果使用数组的结构,队列在数组头部出数据,效率会比较低

2.1 头文件的包含

下面我将带大家一步步实现队列的结构,首先我们需要先书写出所需的头文件

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//判空函数头文件,后文有提及

2.2构造结构体

这里使用了二次封装的结构体,目的是避免使用二重指针修改数据,使函数更简洁

typedef int QDataType;//种类重命名
typedef struct QueueNode
{
	struct QueueNnode* next;
	QDataType data;
}QNode;

typedef struct Queue//包含另一结构体指针的结构体(相当于二次封装),可避免使用二次指针
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

2.3定义相应的函数  

//初始化
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 QueueEmpty(Queue* pq);
// 获取队列中有效元素个数
int QueueSize(Queue* q);

2.4实现相应的函数 

2.4.1 初始化函数

//初始化
void QueueInit(Queue* pq)
{
	//查空、头尾指针置空、对应号为0
	assert(pq);
	pq->head = pq->tail = NULL;//结构体指针,初始化置空
	pq->size = 0;
}

2.4.2 队尾入队列、队头出队列

队尾入队列思路:查空、创建新节点、检查新节点、封装新节点(x,next->NULL)、检查尾指针head或tail(是否无结点)、链接新节点(tail换位)、size++

//队尾入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");//错误返回
		exit(-1);//退出为-1
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}

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

对头出队列思路:验空、验首项、找头、删头释放空间、考虑只有头一项的情况、size-- 

//队头出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->head->next == NULL)//==!!!
	{
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* del = pq->head;
		pq->head = pq->head->next;
		free(del);
	}
	pq->size--;
}

 2.4.3获取队头元素、获取队尾元素

QDataType QueueFront(Queue* pq)
{
	//验空、验首项、return头元素
	assert(pq);
	assert(!QueueEmpty(pq));
	
	return pq->head->data;
}
//获取队尾元素
QDataType QueueBack(Queue* pq)
{
	//验空、验首项、return尾元素
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

 2.4.4 验空函数

检测队列是否为空

// 检测队列是否为空,如果为空返回非零结果,如果非空返回特定公式
int QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL && pq->tail == NULL;
}

2.4.5获取队列中有效元素个数、销毁队列

// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);
	
	return pq->size;
}

销毁队列思路:查空、找头、遍历+释放空间、头尾指针置空 

//销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;//使用与头指针相同的储存类型
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}
	pq->head = pq->tail = NULL;
}

 2.5测试检验

船长解下来会给出对应的测试函数,如果各位看官老爷们有兴趣不妨自己动手试试哦

void TestQueue()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);

	printf("%d ", QueueFront(&q));
	QueuePop(&q);

	printf("%d ", QueueFront(&q));

	QueuePush(&q, 4);
	QueuePush(&q, 4);
	QueuePush(&q, 4);

	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");

	QueueDestroy(&q);
}

int main()
{
	TestQueue();

	return 0;
}

 下面是对应的测试结果:


4.结语

看到这里,相信老铁们对如何实现队列已经有了相应的了解。

我是计算机海洋的新进船长Captain_ldx,如果我的文章能对您有帮助的话,麻烦各位观众姥爷们点赞、收藏、关注,你们的每一次举手之劳都将化为船长的前进动力!


微信公众号

今日签到

点亮在社区的每一天
去签到