数据结构-队列(C语言)

各位好呀,今天我们一起来学习一下队列的内容以及实现队列的操作。

首先:队列是一个只允许一边插入,另一边输出的特殊线性表,具有先进先出FIFO(First In First Out)入队列的原则。出队列的一头称为队头,入队列的一头称为队尾,情况如图。队列可由数组或链表结构实现,链表更优。

了解上述情况后我们可以开始我们基于链表结构的队列的实现,首先我们创建一个工程:工程组成为:源文件:Queue.c和Test.c        头文件:Queue.h。

Queue.c:功能函数的实现补充

Test.c:调试代码

Queue.h:声明功能函数和引用库函数。

基于我们所了解到的内容,我们的结构体需要有两个,一个是代表队列数据类型的QListNode (化简为:QNode)还有代表我们队列的Queue。因为我们的队列是基于链表的结构形成,所以我们的QNode由一个数据类型data 和 指向下一个数据的指针next组成。因为队列中包含队头和队尾的概念,所以Queue结构体中包含了两个QNode指针,一个为队头结点front 一个为队尾结点rear。

我们根据队列的先进先出原则,我们可以构建的基本功能函数有:队列的初始化(QueInit),尾插(QuePushBack),头删(QuePopFront),队列销毁(QueDestory)

队列的初始化(QueInit):我们对于队列的初始化因为我们的扩容问题可以在尾插方面完成,所以我们只需要将Queue结构体中的front指针和rear指针指向NULL即可。

尾插(QuePushBack):在尾插之前,我们创建一个CreateNode功能函数,来为我们创建新数据带来便捷。CreateNode函数中,我们创建一个newnode,使用malloc函数创建一个大小为QNode的空间,将新的数据值赋值给data,将next指向NULL。最后返回我们的newnode。

在QuePushBack中,我们先使用CreateNode来为我们创建一个新的QNode:newnode,然后我们需要对Queue进行判断,如果我们的队列当前没有数据,那么我们需要将我们的front指针和rear指针同时指向newnode,然后返回。如果我们是有数据的,那么我们需要将我们的rear指针指向的数据的下一位设置为newnode,然后将我们的newnode设置为我们的rear指针。

头删(QuePopFront):头删时,我们先创建一个QNode类型的数据:tmp用于存储我们当前的front指针指向的数据,然后将front指针选项后移动一位,再将tmp释放即可。

队列销毁(QueDestory):这里我们设置一个QNode类型的指针:tmp指向我们的front指针指向的数据,然后使用while函数循环遍历队列,逐一释放,当tmp==NULL时我们的队列空间释放完成,之后将tmp指向NULL,front和rear指针也指向NULL即可。

完成上述操作后,大家可以在Test.c中调试我们的代码,使用F11来逐步观察我们的队列内部状况。

接下来我们再补充几个功能函数来让我们的队列更加完美:获取队列头元素(QueueFront),获取队列队尾元素(QueueBack),获取队列中有效元素个数(QueueSize),检查队列是否为空,如果为空返回非零结果,如果非空返回0(QueueEmpty)。

获取队列头元素(QueueFront),获取队列队尾元素(QueueBack):这俩功能函数返回情况接近,所以我给大家放在一起。我们只需要返回我们front指针或rear指针所指向的数据的data元素即可。:

获取队列中有效元素个数(QueueSize):这里我们设置一个int类型的size , 然后我们创建一个QNode的指针:tmp指向我们的front所指向的队头数据,然后使用while遍历,每一次size++,且tmo指向下一个数据,当tmp==NULL时,while循环终止。此时我们的size就记录了当前队列中的数据个数。

检查队列是否为空,如果为空返回非零结果,如果非空返回0(QueueEmpty):我们只需要判断front指向是否为NULL即可:

通过以上的功能函数结合,我们就得到一个功能相对完备的队列啦。上述文章有任何没看懂的小伙伴们可以问我哦。如果有任何需要修改和改进的内容,欢迎各位指出纠正哈。代码如下:

//Queue.c
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
//初始化
void QueInit(Queue* q)
{
	assert(q);
	q->front = NULL;
	q->rear = NULL;
}
QNode* CreatQNode(QDataType x)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("amlloc");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
}
//尾插
void QuePushBack(Queue* q, QDataType x)
{
	assert(q);
	QNode* newnode= CreatQNode(x);
	if (q->front == NULL)
	{
		q->front = q->rear = newnode;
		return;
	}
	q->rear->next = newnode;
	q->rear = newnode;
}
//头出
void QuePopFront(Queue* q)
{
	assert(q);
	QNode* tmp = q->front;
	q->front = q->front->next;
	free(tmp);
	tmp = NULL;
}
//获取队列头元素
QDataType QueueFront(Queue* q)
{
	return q->front->data;
}
//获取队列队尾元素
QDataType QueueBack(Queue* q)
{
	return q->rear->data;
}
//获取队列中有效元素个数
int QueueSize(Queue* q)
{
	int size = 0;
	QNode* tmp = q->front;
	while (tmp != NULL)
	{
		tmp = tmp->next;
		size++;
	}
	return size;
}
//检查队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q)
{
	if (q->front == NULL)
	{
		return -1;
	}
	else
		return 0;
}
//销毁队列
void QueueDestroy(Queue* q)
{
	QNode* tmp = q->front;
	while (tmp != NULL)
	{
		QNode* tmpnext = tmp->next;
		free(tmp);
		tmp = tmpnext;
	}
	tmp = NULL;
	q->front = q->rear = NULL;
}
//Queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;
typedef struct Queue
{
	QNode* front;
	QNode* rear;
}Queue;

//初始化
void QueInit(Queue* q);
//尾插
void QuePushBack(Queue* q, QDataType x);
//头出
void QuePopFront(Queue* q);
//销毁队列
void QueueDestroy(Queue* q);
//获取队列头元素
QDataType QueueFront(Queue* q);
//获取队列队尾元素
QDataType QueueBack(Queue* q);
//获取队列中有效元素个数
int QueueSize(Queue* q);
//检查队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);


 
//Test.c
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"

void Test1()
{
	Queue que;
	QueInit(&que);
	int z = QueueEmpty(&que);
	QuePushBack(&que, 1);
	QuePushBack(&que, 2);
	QuePushBack(&que, 3);
	QuePushBack(&que, 4);
	z = QueueEmpty(&que);
	QDataType i =  QueueFront(&que);
	int s = QueueSize(&que);
	QuePopFront(&que);
	i = QueueFront(&que);
	i = QueueBack(&que);
	s = QueueSize(&que);
	QueueDestroy(&que);
}

int main()
{
	Test1();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值