数据结构-队列



🦆 个人主页:深邃-

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

测试提交


相关推荐
程序员Shawn2 小时前
【机器学习 | 第六篇】- 机器学习
人工智能·算法·机器学习·集成学习
Rhystt2 小时前
代码随想录算法训练营第六十天|多余的边?从基础到进阶!
开发语言·c++·算法·图论
羊小猪~~2 小时前
【QT】-- QMainWindow简介
开发语言·数据库·c++·后端·qt·前端框架·求职招聘
2301_810160952 小时前
C++中的策略模式进阶
开发语言·c++·算法
keep intensify2 小时前
二叉树的直径
数据结构·算法·深度优先
-Rane2 小时前
【C++】map和set
开发语言·c++
keep intensify2 小时前
单源最短路径
数据结构·c++·算法
2401_873544922 小时前
分布式缓存一致性
开发语言·c++·算法
香芋超新星2 小时前
反转字符串中的小写字母
算法