数据结构--队列【详解】~(˶‾᷄ꈊ‾᷅˵)~

目录

队列定义:

 队列的声明与头文件的包含:

队列的声明: 

头文件的包含: 

队列的基本操作: 

初始化队列 : 

 摧毁队列:

 入队列:

 出队列:

返回队头数据:

返回队尾数据:

返回队列当前大小:

判空操作:

测试数据: 

最后,完整代码:


队列定义:

队列是一个先进先出的数据结构(First in First out)。只能对表尾进行插入,对表头进行结点的删除,这样强限制性的链表,这就是所说的队列。也就是说,队列是限定在表的一端进行插入,表的另一端进行删除的数据结构。

图解:

 如同日常生活中去买票排队,每一列队伍都有一个队尾和队首,先来的先买票,后来的后买,买好的就从队首出去,新来买票的就需要从队尾继续排队。

为了使用的方便,咱们将队头位置的指针命名为head,队尾为tail 

 队列的声明与头文件的包含:

队列的声明: 

typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue//定义类型为QNode的指向队头和队尾的指针
{QNode* head;QNode* tail;
}Queue;

这里通过单链表实现队列,需要一个单链表的结构QueueNode。然后头尾指针需要另外开辟一个结构体,指针的类型是QNode*. 通过指针head和tail来查询队列中的队头和队尾数据。

头文件的包含: 

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

队列的基本操作: 

//初始化队列
void QueueInit(Queue* pq);
//摧毁队列
void QueueDestory(Queue* pq);//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);
//返回队头数据
QDataType QueueFront(Queue* pq);
//返回队尾数据
QDataType QueueBack(Queue* pq);
//返回队列当前大小
int QueueSize(Queue* pq);
//判空操作
bool QueueEmpty(Queue* pq);

 

初始化队列 : 

void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;//将指向队头和队尾的指针置空
}

 摧毁队列:

void QueueDestory(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;//保存下一个节点的指针,释放当亲位置的空间free(cur);cur = next;}pq->head = pq->tail = NULL;//释放完后将队头和队尾指针都置空
}

 入队列:

void QueuePush(Queue* pq,QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)//为新节点开辟空间{printf("malloc fail\n");exit(-1);}newnode->data = x;newnode->next = NULL;//为新节点赋值if (pq->tail == NULL)//若当前尾为空,就将队头,尾指针指向newnode{pq->tail = pq->head = newnode;}else{pq->tail->next = newnode;//否则队尾指针的next指向newnodepq->tail = newnode;}
}

1.入队列前需要开辟一个新节点,同时进行判空操作

2.进行入队操作的时候,首先需要判断队列是否为空,如果队列为空的话,需要将头指针和尾指针一同指向第一个结点 

3.如果不为空,就进行队列的尾插操作,同时移动tail的位置以便于下一次的插入

 

 出队列:

void QueuePop(Queue* pq)
{assert(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;}
}

出队列是需要判断当前队列中的节点个数,分为一个和多个进行讨论。如果只有一个,就将头节点内存释放,接着将头尾指针置空,防止野指针的出现。如果是多个节点,就需要将头节点的下一个节点保存,以免找不到。接着将头节点内存释放,释放后,移动头指针head的位置,使其指向下一个节点。 

返回队头数据:

QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->head);return pq->head->data;
}

返回队尾数据:

QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->head);return pq->tail->data;
}

返回队列当前大小:

int QueueSize(Queue* pq)
{assert(pq);int size = 0;QNode* cur = pq->head;while (cur){size++;cur = cur->next;}return size;
}

判空操作:

bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}

测试数据: 

 

最后,完整代码:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue//定义类型为QNode的指向队头和队尾的指针
{QNode* head;QNode* tail;
}Queue;
//初始化队列
void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;//将指向队头和队尾的指针置空
}
//摧毁队列
void QueueDestory(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;//保存下一个节点的指针,释放当亲位置的空间free(cur);cur = next;}pq->head = pq->tail = NULL;//释放完后将队头和队尾指针都置空
}
//入队列
void QueuePush(Queue* pq,QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)//为新节点开辟空间{printf("malloc fail\n");exit(-1);}newnode->data = x;newnode->next = NULL;//为新节点赋值if (pq->tail == NULL)//若当前尾为空,就将队头,尾指针指向newnode{pq->tail = pq->head = newnode;}else{pq->tail->next = newnode;//否则队尾指针的next指向newnodepq->tail = newnode;}
}
//出队列
void QueuePop(Queue* pq)
{assert(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;}
}
//返回队头数据
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->head);return pq->head->data;
}
//返回队尾数据
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->head);return pq->tail->data;
}
//返回队列当前大小
int QueueSize(Queue* pq)
{assert(pq);int size = 0;QNode* cur = pq->head;while (cur){size++;cur = cur->next;}return size;
}
//判空操作
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}void QueueTest()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);printf("%d ", QueueFront(&q));QueuePop(&q);printf("%d ", QueueFront(&q));QueuePop(&q);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}printf("\n");QueueDestory(&q);
}
int main()
{QueueTest();return 0;
}

 博客到这里也是结束了,喜欢的小伙伴可以点赞加关注支持下博主,这对我真的很重要~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/313839.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区分LR(0),SLR(1),LR(1)和LALR(1)

目录 对于LR(0)文法&#xff1a; 对于SLR(1)文法&#xff1a; 对于LR(0)和SLR(1)文法&#xff1a; 对于LR(1)和SLR(1)文法&#xff1a; 对于LALR(1)文法&#xff1a; 例题1&#xff1a; 例题2&#xff1a; 例题3&#xff1a; 例题4&#xff1a; 这几个文法大致的步骤都…

适用于各种危险区域的火焰识别摄像机,实时监测、火灾预防、安全监控,为安全保驾护航

火灾是一种极具破坏力的灾难&#xff0c;对人们的生命和财产造成了严重的威胁。为了更好地预防和防范火灾&#xff0c;火焰识别摄像机作为一种先进的监控设备&#xff0c;正逐渐受到人们的重视和应用。本文将介绍火焰识别摄像机在安全监控和火灾预防方面的全面应用方案。 一、火…

29 UVM Command Line Processor (CLP)

随着设计和验证环境的复杂性增加&#xff0c;编译时间也增加了&#xff0c;这也影响了验证时间。因此&#xff0c;需要对其进行优化&#xff0c;以便在不强制重新编译的情况下考虑新的配置或参数。我们已经看到了function or task如何基于传递参数进行行为。类似地&#xff0c;…

2023结婚成家,2024借势起飞

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

【Redis-05】Redis如何实现保存键值对的保存及过期键的管理策略

在之前的文章我们介绍过&#xff0c;Redis服务器在启动之初&#xff0c;会初始化RedisServer的实例&#xff0c;在这个实例中存在很多重要的属性结构&#xff0c;同理本篇博客中介绍的数据库实现原理也会和其中的某些属性相关&#xff0c;我们继续看一下吧。 1.服务器和客户端…

2.3物理层下面的传输媒体

目录 2.3物理层下面的传输媒体2.3.1导引型传输媒体1.双绞线2.同轴电缆3.光纤 2.3.2非导引型传输媒体无线电微波通信 2.3物理层下面的传输媒体 传输媒体是数据传输系统中在发送器和接收器之间的物理通路 两大类&#xff1a; 导引型传输媒体&#xff1a;电磁波被导引沿着固体媒体…

微信小程序开发系列-11组件间通信02

微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》 《微信小程序开发系列-02注册小程序》 《微信小程序开发系列-03全局配置中的“window”和“tabBar”》 《微信小程序开发系列-04获取用户图像和昵称》 《微信小程序开发系列-05登录小程序》 《…

连接progressql报错Cannot load JDBC driver class ‘org.postgresql.Driver‘,亲测有效!!!

Jmeter连接progressql报错Cannot load JDBC driver class ‘org.postgresql.Driver’ 1.到官方下载驱动注意&#xff1a;根据项目的JDK版本来下载对应的驱动Download | pgJDBC 2.将postgresql-42.2.27.jar复制到lib目录下面&#xff0c; 然后重新启动 连接driver信息如下&#…

事务失效的十种常见场景

学习事务失效场景 1 概述 事务的传播类型isolationTransactionnal注解属性 事务方法未被Spring管理方法使用final类型修饰非public修饰的方法同一个类中的方法相互调用方法的事务传播类型不支持事务异常被内部catch&#xff0c;程序生吞异常数据库不支持事务未配置开启事务错…

golang锁源码【只有关键逻辑】

条件锁 type Cond struct {L Lockernotify notifyList } type notifyList struct {wait uint32 //表示当前 Wait 的最大 ticket 值notify uint32 //表示目前已唤醒的 goroutine 的 ticket 的最大值lock uintptr // key field of the mutexhead unsafe.Pointer //链表头…

simulink代码生成(六)——多级中断的配置

假如系统中存在多个中断&#xff0c;需要合理的配置中断的优先级与中断向量表&#xff1b;在代码生成中&#xff0c;要与中断向量表对应&#xff1b;中断相关的知识参照博客&#xff1a; DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…

Python pygame贪吃蛇小游戏 (200行完整代码+注释+可运行)

一、运行效果图 二、完整代码 #!/usr/bin/env python # -*- coding: utf-8 -*- # author&#xff1a;Wangdali time:2021年1月20日16:08:44 #python实现&#xff1a;贪吃蛇游戏玩法&#xff1a;回车开始游戏&#xff1b;空格暂停游戏/继续游戏&#xff1b;方向键/wsad控制小蛇…