数据结构-队列



🦆 个人主页:深邃-

❄️专栏传送门:《C语言》《数据结构》

🌟Gitee仓库:《C语言》《数据结构》


队列目录

概念与结构

概念

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

队列底层结构选型

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低
相反链表标记头节点,尾节点,这样实现的队列,时间复杂度均为O(1)

队列结构

Q u e u e . h Queue.h Queue.h

c 复制代码
typedef int QDataType;
//定义节点结构
typedef struct QueueNode {
	QDataType data;
	struct QueueNode* next;
}QueueNode;

//定义队列的结构
typedef struct Queue {
	QueueNode* phead; //队头
	QueueNode* ptail; //队尾
	//int size;         //队列中有效数据个数
}Queue;

接下来待实现的函数声明以及头文件 接下来待实现的函数声明以及头文件 接下来待实现的函数声明以及头文件

c 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
``//初始化
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);

队列的实现

Q u e u e . c Queue.c Queue.c

初始化队列

c 复制代码
//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
}

入队列

思路:创建一个节点,插入队列中,注意判断队列是否为空

c 复制代码
//入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	//创建值为x的节点
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	//队列为空
	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else {
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
}

判断队列是否为空

c 复制代码
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL;
}

出队列

出队列,队头出,注意剩一个元素的特殊情况

c 复制代码
//出队列
void QueuePop(Queue* pq)
{
	assert(!QueueEmpty(pq));

	//队列中只有一个节点
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else {
		QueueNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
}

取队头数据

c 复制代码
//取队头数据
QDataType QueueFront(Queue* pq)
{
	assert(!QueueEmpty(pq));
	return pq->phead->data;
}

取队尾数据

c 复制代码
//取队尾数据
QDataType QueueBack(Queue* pq)
{
	assert(!QueueEmpty(pq));
	return pq->ptail->data;
}

队列有效元素个数

c 复制代码
//队列有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* pcur = pq->phead;
	int size = 0;
	while (pcur)
	{
		++size;
		pcur = pcur->next;
	}
	return size;

	//return pq->size;
}

优化思路:在队列中加入size元素

c 复制代码
//定义队列的结构 
typedef struct Queue
{ 	
	QueueNode* phead; //队头
	QueueNode* ptail; //队尾 	
	int size;         //队列中有效数据个数 
}Queue; 
c 复制代码
//队列有效元素个数
int QueueSize(Queue* pq)
{
	return pq->size;
}

队列的销毁

c 复制代码
//销毁
void QueueDesTroy(Queue* pq)
{
	assert(pq);

	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	pq->phead = pq->ptail = NULL;
}

队列算法题

用队列实现栈

题目链接:用队列实现栈

  • 题目讲解

思路:
入栈:往不为空的队列中插入数据
出栈:把不为空队列中前size-1个数据挪到另一个队列,再将最后一个数据出队列
取栈顶(不出数据):找不为空的队列,返回队尾数据

栈结构

c 复制代码
//两个队列实现一个栈
typedef struct {
	Queue q1;
	Queue q2;
} MyStack;

创建一个栈

c 复制代码
//创建一个栈
MyStack* myStackCreate() {
	MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
	QueueInit(&pst->q1);
	QueueInit(&pst->q2);
	return pst;
}

入栈

c 复制代码
void myStackPush(MyStack* obj, int x) {
	//往不为空的队列中插入数据
	if (!QueueEmpty(&obj->q1))
	{
		//q1
		QueuePush(&obj->q1, x);
	}
	else {
		//q2
		QueuePush(&obj->q2, x);
	}
}

出栈

c 复制代码
int myStackPop(MyStack* obj) {
	//找不为空队列
	Queue* emp = &obj->q1;
	Queue* noneEmp = &obj->q2;
	if (QueueEmpty(&obj->q2))
	{
		emp = &obj->q2;
		noneEmp = &obj->q1;
	}
	//不为空队列前size-1个数据挪到空队列中
	while (QueueSize(noneEmp) > 1)
	{
		//取队头,入另一个队列
		QueuePush(emp, QueueFront(noneEmp));
		//出队头
		QueuePop(noneEmp);
	}
	//不为空队列数据出队
	int top = QueueFront(noneEmp);
	QueuePop(noneEmp);
	return top;
}

取栈顶

c 复制代码
//取栈顶
int myStackTop(MyStack* obj) {
	//找不为空队列,返回不为空队列的队尾数据
	if (!QueueEmpty(&obj->q1))
	{
		return QueueBack(&obj->q1);
	}
	else {
		return QueueBack(&obj->q2);
	}
}

栈判空

c 复制代码
bool myStackEmpty(MyStack* obj) {
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

栈销毁

c 复制代码
void myStackFree(MyStack* obj) {
	QueueDesTroy(&obj->q1);
	QueueDesTroy(&obj->q2);
	free(obj);
	obj = NULL;
}

测试提交


相关推荐
斯内科19 小时前
四胞胎素数:找出‌个位数分别是 1、3、7、9‌,且‌十位及更高位数字完全相同‌的质数,例如 11、13、17、19
算法·质数·素数·四胞胎素数
Hello.Reader19 小时前
算法基础(十二)——主方法:快速求解常见递归式
算法
想唱rap19 小时前
传输层协议TCP
linux·运维·服务器·网络·c++·tcp/ip
小O的算法实验室20 小时前
2026年IEEE TITS,面向按需外卖配送调度的特定问题知识与基于学习元启发式算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
加勒比海带6620 小时前
目标检测算法——农林行业数据集汇总附下载链接【Plant】
大数据·图像处理·人工智能·算法·目标检测
洛水水20 小时前
【力扣100题】23. 螺旋矩阵
算法·leetcode·矩阵
瑶池酒剑仙20 小时前
C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)
c语言·开发语言·c++·visual studio
三品吉他手会点灯20 小时前
C语言学习笔记 - 27.C编程预备计算机专业知识 - 什么是字节
c语言·开发语言·笔记·学习
影sir20 小时前
不同测试数据下,该如何选择算法
算法·深度优先
潇湘散客20 小时前
CAX软件插件化设计实现牛刀小试
c++·算法·图形学·opengl