数据结构—队列的实现

前言:上次我们已经学习了数据结构中一个重要的线性表---栈,那么我们这一次就来学习另外一个重要的线性表---队列。

目录:

一、
队列的概念
二、
队列的实现:
1.队列的创建
三、
队列的操作
1.初始化队列
2.队尾入队列
3.队头出队列
4.获取队列头部元素
5.获取队列队尾元素
6.获取队列中有效元素个数
7.检测队列是否为空,如果为空返回非零结果,如果非空返回0
8.销毁队列
四、
完整代码展示

队列的概念

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

队列的实现

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

我们用三个文件来完成对它的操作。

队列的创建:

c 复制代码
typedef int QDataType;
// 链式结构:表示队列
typedef struct QueueNode
{
	QDataType val;
	struct QueueNode* next;
}QNode;

// 队列的结构
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

队列的实现:

队列的初始化:

c 复制代码
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

队列里的头和尾都为空。

队尾入队列:

c 复制代码
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

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

	newnode->val = x;
	newnode->next = NULL;

	if (pq->ptail == NULL)
	{
		pq->ptail = pq->phead = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}

	pq->size++;
}

如果我们的队尾元素为空,那么我们的队尾就是newnode,如果我们的队尾不为空,我们的ptail的下一个指向newnode,现在的队尾就为newnode。

队头出队列:

c 复制代码
void QueuePop(Queue* pq)
{
	assert(pq);
	// 
	assert(pq->phead);

	QNode* del = pq->phead;
	pq->phead = pq->phead->next;
	free(del);
	del = NULL;

	if (pq->phead == NULL)
		pq->ptail = NULL;

	pq->size--;
}

如果我们直接删除队头元素那么我们就无法访问下一个元素,所以我们先把队头元素保存起来,让现在的队头元素为原来队头元素的下一个元素,在给原来的队头元素删除。

获取队列头部元素:

c 复制代码
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	// 
	assert(pq->phead);

	return pq->phead->val;
}

获取队列队尾元素:

c 复制代码
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	// 
	assert(pq->ptail);

	return pq->ptail->val;
}

获取队列中有效元素个数:

c 复制代码
int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

size就是我们有效元素的个数,这里返回size就可以了。

检测队列是否为空,如果为空返回非零结果,如果非空返回0:

c 复制代码
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->phead == NULL;
}

队列为空返回0,不为空返回非0,后面测试代码的循环条件就是不为0,就输出,为0就跳出循环。

销毁队列:

c 复制代码
void QueueDestroy(Queue* pq)
{
	assert(pq);

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

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

完整代码展示:

Queue.h:

c 复制代码
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>

typedef int QDataType;
typedef struct QueueNode
{
	QDataType val;
	struct QueueNode* next;
}QNode;

typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int 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);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);

Queue.c:

c 复制代码
#include"Queue.h"

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);

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

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

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

	newnode->val = x;
	newnode->next = NULL;

	if (pq->ptail == NULL)
	{
		pq->ptail = pq->phead = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}

	pq->size++;
}

void QueuePop(Queue* pq)
{
	assert(pq);
	// 
	assert(pq->phead);

	QNode* del = pq->phead;
	pq->phead = pq->phead->next;
	free(del);
	del = NULL;

	if (pq->phead == NULL)
		pq->ptail = NULL;

	pq->size--;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	// 
	assert(pq->phead);

	return pq->phead->val;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	// 
	assert(pq->ptail);

	return pq->ptail->val;
}

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

	return pq->phead == NULL;
}

int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

代码测试:

test.c:

c 复制代码
#include"Queue.h"
int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);

	QueuePush(&q, 4);
	QueuePush(&q, 5);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}

	QueueDestroy(&q);

	return 0;
}

这里我们先入队1,2,3,队头就是1,队尾就是3,我们在出队,先输出1,在把1出队,这样我们就访问2,在输出2之后把2出队,入队4,5,如果我们的队列不为0就输出3,4,5。最后输出的结果如下图:

相信大家一定可以完美的拿捏队列,感谢各位小伙伴的支持,我们下期再见!

相关推荐
Natsume17101 小时前
嵌入式开发:GPIO、UART、SPI、I2C 驱动开发详解与实战案例
c语言·驱动开发·stm32·嵌入式硬件·mcu·架构·github
shaun20011 小时前
华为c编程规范
c语言
MeshddY2 小时前
(超详细)数据库项目初体验:使用C语言连接数据库完成短地址服务(本地运行版)
c语言·数据库·单片机
森焱森2 小时前
无人机三轴稳定化控制(1)____飞机的稳定控制逻辑
c语言·单片机·算法·无人机
呆瑜nuage2 小时前
数据结构——堆
数据结构
蓝澈11212 小时前
弗洛伊德(Floyd)算法-各个顶点之间的最短路径问题
java·数据结构·动态规划
zl_dfq2 小时前
数据结构 之 【堆】(堆的概念及结构、大根堆的实现、向上调整法、向下调整法)(C语言实现)
数据结构
127_127_1272 小时前
2025 FJCPC 复建 VP
数据结构·图论·模拟·ad-hoc·分治·转化
闪电麦坤952 小时前
数据结构:二维数组(2D Arrays)
数据结构·算法
凌肖战3 小时前
力扣网C语言编程题:快慢指针来解决 “寻找重复数”
c语言·算法·leetcode