数据结构-队列



🦆 个人主页:深邃-

❄️专栏传送门:《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;
}

测试提交


相关推荐
小月土星1 分钟前
JavaScript 快速排序:从 pivot、双指针到分治思想
javascript·算法·面试
小月土星8 分钟前
JavaScript 递归入门:从 1 到 n 求和,再到数组扁平化
javascript·算法·面试
To_OC15 小时前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
鱼鱼不愚与20 小时前
《原来如此 | 第01期:为什么导航软件能预测红绿灯倒计时?》
算法
博客18001 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴1 天前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake
复杂网络1 天前
论最小 Agent 计算机的形态
算法
kisshyshy2 天前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
众少成多积小致巨2 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++