数据结构5——队列

1. 队列的概念及结构

队列的概念:

与栈相比,队列也是一种特殊的线性表,不同的是,队列只允许在一端进行插入数据操作,在另一端进行删除数据操作。队列遵守先进先出 FIFO(First In First Out)的原则。

入队列:进行插入操作的一端称为队尾。

出队列:进行删除操作的一端称为队头。

图解:

2. 队列的实现

1. 队列节点

链表和数组都能实现队列,但相比之下,链表更优,因为数组出队列时在数组头上出数据,效率会比较低。

复制代码
//队列节点
typedef int QDataType;
//链表和数组都能实现队列,但相比之下
//链表更优,因为数组出队列时在数组头上出数据,效率会比较低。
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

2. "Que"结构体

增加一个尾指针方便找尾,头指针和尾指针定义为结构体方便传参。

复制代码
//增加一个尾指针方便找尾,头指针和尾指针定义为结构体方便传参
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Que;

3. 初始化

复制代码
//初始化
void QueueInit(Que* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

4. 销毁

复制代码
//销毁
void QueueDestroy(Que* pq)
{
	assert(pq);

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

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

5. 入队列

复制代码
//入队列
void QueuePush(Que* pq, QDataType x)
{
	assert(pq);

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

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

	//如果队列为空
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

6. 出队列

复制代码
//出队列
void QueuePop(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));//队列为空不能删除

	if (pq->head->next == NULL)//剩一个节点时,要避免尾指针成为野指针
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}

	pq->size--;
}

7. 取队头数据

复制代码
//取队头数据
QDataType QueueFront(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

8. 取队尾数据

复制代码
QDataType QueueBack(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

9.判空

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

	return pq->head == NULL;
}

10. 求队列大小

复制代码
//求队列大小
int QueueSize(Que* pq)
{
	assert(pq);

	return pq->size;
}

3. 测试

复制代码
int main()
{
	Que q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);


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

	QueueDestroy(&q);
	return 0;
}


源代码

Queue.h

复制代码
#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

//队列节点
typedef int QDataType;
//链表和数组都能实现队列,但相比之下
//链表更优,因为数组出队列时在数组头上出数据,效率会比较低。
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

//增加一个尾指针方便找尾,头指针和尾指针定义为结构体方便传参
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Que;

//初始化
void QueueInit(Que* pq);
//销毁
void QueueDestroy(Que* pq);
//入队列
void QueuePush(Que* pq, QDataType x);
//出队列
void QueuePop(Que* pq);
//取队头数据
QDataType QueueFront(Que* pq);
//取队尾数据
QDataType QueueBack(Que* pq);
//判空
bool QueueEmpty(Que* pq);
//求队列大小
int QueueSize(Que* pq);

Queue.c

复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include "Queue.h"

//初始化
void QueueInit(Que* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

//销毁
void QueueDestroy(Que* pq)
{
	assert(pq);

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

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

//入队列
void QueuePush(Que* pq, QDataType x)
{
	assert(pq);

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

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

	//如果队列为空
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

//出队列
void QueuePop(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));//队列为空不能删除

	if (pq->head->next == NULL)//剩一个节点时,要避免尾指针成为野指针
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}

	pq->size--;
}

//取队头数据
QDataType QueueFront(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

//取队尾数据
QDataType QueueBack(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

//判空
bool QueueEmpty(Que* pq)
{
	assert(pq);

	return pq->head == NULL;
}

//求队列大小
int QueueSize(Que* pq)
{
	assert(pq);

	return pq->size;
}

test.c

复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include "Queue.h"

int main()
{
	Que q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);


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

	QueueDestroy(&q);
	return 0;
}
相关推荐
Lisssaa5 分钟前
打卡第二十八天
数据结构·算法
weixin_6495556722 分钟前
C语言程序设计第四版(何钦铭、颜晖)第十一章指针进阶之查找星期
数据结构·算法
北顾笙98026 分钟前
day10-数据结构力扣
数据结构
炘爚38 分钟前
C++(普通指针和成员的区别、指针的使用场景和存储内容)
数据结构·c++·算法
Book思议-39 分钟前
【数据结构考研真题】栈和队列(小题)
数据结构·考研·栈和队列·408小题
阿Y加油吧1 小时前
面试硬核双杀!合并 K 个升序链表 + LRU 缓存|力扣高频手撕原题全解
数据结构·leetcode·链表
是翔仔呐1 小时前
第10章 串口通信USART全解:轮询/中断/DMA三种收发模式与上位机通信实战
c语言·开发语言·stm32·单片机·嵌入式硬件·学习·gitee
计算机安禾1 小时前
【数据结构与算法】第12篇:栈(二):链式栈与括号匹配问题
c语言·数据结构·c++·学习·算法·visual studio code·visual studio
散峰而望2 小时前
【数据结构】单调栈与单调队列深度解析:从模板到实战,一网打尽
开发语言·数据结构·c++·后端·算法·github·推荐算法
杨校2 小时前
杨校老师课堂备战C++之数据结构中栈结构专题训练
开发语言·数据结构·c++