数据结构 严薇敏 队列 的实现及其使用方法详解
目录
1.队列
1.1队列的概念及结构
1.2队列的实现
1.3接口以及实现
Queue.h
Queue.c
申请一个队列的节点
初始化队列
入队列
出队列
查找队头元素
查找队尾元素
获取队列长度
判断是否为空队列
队列的销毁
测试用例
1.队列
1.1队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头,形象一点就是吃进去拉出来
1.2队列的实现
可以用顺序结构来实现,也可以用链式结构实现,但是顺序结构要搬运元素 ,头插尾删就比较耗时间,所以采用链式结构来实现,一个带头借点的单链表。
1.3接口以及实现
Queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>typedef int Datatype;typedef struct Queuenode{struct Queuenode* next;Datatype data;
}Queuenode;typedef struct Queue {Queuenode* front;Queuenode* back;
}Queue;//申请一个队列的节点
Queuenode* CreateQueueNode(Datatype data);//初始化队列
void QueueInit(Queue* p);//入队列
void QueuePush(Queue* p, Datatype data);//出队列
void QueuePop(Queue* p);//查找队头元素
Datatype QueueFront(Queue* p);//查找队尾元素
Datatype QueueBack(Queue* p);//获取队列长度
int QueueSize(Queue* p);//判断是否为空队列
int QueueEmpty(Queue* p);//队列的销毁
void QueueDestory(Queue* p);
Queue.c
#include "Queue.h"
//申请一个队列的节点
//相当一个带头结点的单链表
Queuenode* CreateQueueNode(Datatype data)
{//直接malloc一个Queuenode* Newnode = (Queuenode*)malloc(sizeof(Queuenode));//查看是否申请成功if (NULL == Newnode) {assert(0);return NULL;}//更新节点数据Newnode->data = data;Newnode->next = NULL;return Newnode;
}//初始化队列
void QueueInit(Queue* p)
{//参数传入的判断assert(p);//给一个头结点p->front = CreateQueueNode(0);p->back = p->front;
}//入队列
//其实就是带头单链表的尾插
void QueuePush(Queue* p, Datatype data)
{//传入参数的合法性判断assert(p);//申请一个节点把传入数据放进去Queuenode* Newnode = CreateQueueNode(data);//直接尾插,next指针指向这个新节点,把他连接起来p->back->next = Newnode;p->back = Newnode;
}//出队列
//其实就是带头单链表的头删
void QueuePop(Queue* p)
{Queuenode* Delnode = NULL;//先判断是否为空if (QueueEmpty(p)) {return;}//标记删除节点,头删Delnode = p->front->next;//然后在连接起来p->front->next = Delnode->next;//队列中刚好只有一个元素,删除之后应该要将队尾back放在头节点的位置if (Delnode == p->back) {p->back = p->front;}free(Delnode);
}//查找队头元素
Datatype QueueFront(Queue* p)
{//对传入参数合法性的判断assert(p);return p->front->next->data;
}//查找队尾元素
Datatype QueueBack(Queue* p)
{//对传入参数合法性的判断assert(p);return p->back->data;
}//获取队列长度
int QueueSize(Queue* p)
{//对传入参数合法性的判断assert(p);//哎呦 这不是我的老朋友计数器吗int count = 0;//好家伙 这不是老伙计遍历指针Queuenode* cur = p->front->next;while (cur) {count++;cur = cur->next;}return count;
}//判断是否为空队列
int QueueEmpty(Queue* p)
{//对传入参数合法性的判断assert(p);//俩指针都指向头结点这不就是空队列了return p->front == p->back;
}//队列的销毁
void QueueDestory(Queue* p)
{//对传入参数合法性的判断assert(p);//先来一个便利指针Queuenode* cur = p->front->next;while (cur) {//这个队头指针一个个指向下一个节点p->front->next = cur->next;free(cur);cur = p->front->next;}free(p->front);p->back = NULL;p->front = NULL;
}//测试用例
void text() {Queue p;QueueInit(&p);printf("size = %d\n", QueueSize(&p));printf("\n");// 入队列QueuePush(&p, 1);QueuePush(&p, 2);QueuePush(&p, 3);QueuePush(&p, 4);QueuePush(&p, 5);QueuePush(&p, 6);QueuePush(&p, 7);printf("size = %d\n", QueueSize(&p));printf("front = %d\n", QueueFront(&p));printf("back = %d\n", QueueBack(&p));printf("\n");// 出队列QueuePop(&p);printf("size = %d\n", QueueSize(&p));printf("front = %d\n", QueueFront(&p));printf("back = %d\n", QueueBack(&p));printf("\n");QueuePop(&p);QueuePop(&p);QueuePop(&p);QueuePop(&p);QueuePop(&p);printf("size = %d\n", QueueSize(&p));printf("front = %d\n", QueueFront(&p));printf("back = %d\n", QueueBack(&p));printf("\n");QueuePop(&p);QueuePop(&p);printf("size = %d\n", QueueSize(&p));QueueDestory(&p);
}
int main() {text();
}
申请一个队列的节点
//申请一个队列的节点
//相当一个带头结点的单链表
Queuenode* CreateQueueNode(Datatype data)
{//直接malloc一个Queuenode* Newnode = (Queuenode*)malloc(sizeof(Queuenode));//查看是否申请成功if (NULL == Newnode) {assert(0);return NULL;}//更新节点数据Newnode->data = data;Newnode->next = NULL;return Newnode;
}
- 先malloc一个节点
- 判断是否申请成功
- 再更新节点数据
初始化队列
//初始化队列
void QueueInit(Queue* p)
{//参数传入的判断assert(p);//给一个头结点p->front = CreateQueueNode(0);p->back = p->front;
}
- 直接用刚刚那个方法,创建新的节点。
- 首尾都指向这个头结点。
入队列
//入队列
//其实就是带头单链表的尾插
void QueuePush(Queue* p, Datatype data)
{//传入参数的合法性判断assert(p);//申请一个节点把传入数据放进去Queuenode* Newnode = CreateQueueNode(data);//直接尾插,next指针指向这个新节点,把他连接起来p->back->next = Newnode;p->back = Newnode;
}
- 先调用刚才的方法来申请一个节点,然后放在队尾。
- 队尾指针的next指向这个新节点,队尾指针再往后移动一下,指向现在这个节点。
出队列
//出队列
//其实就是带头单链表的头删
void QueuePop(Queue* p)
{Queuenode* Delnode = NULL;//先判断是否为空if (QueueEmpty(p)) {return;}//标记删除节点,头删Delnode = p->front->next;//然后在连接起来p->front->next = Delnode->next;//队列中刚好只有一个元素,删除之后应该要将队尾back放在头节点的位置if (Delnode == p->back) {p->back = p->front;}free(Delnode);
}
- 头出队列先用DelNode标记要删除的节点。
- 移动头指针,让头结点出队列。
- 队列中刚好只有一个元素,删除之后应该要将队尾back放在头节点的位置
查找队头元素
//查找队头元素
Datatype QueueFront(Queue* p)
{//对传入参数合法性的判断assert(p);return p->front->next->data;
}
- 直接指针找到头结点下一个的数据域然后返回。
查找队尾元素
//查找队尾元素
Datatype QueueBack(Queue* p)
{//对传入参数合法性的判断assert(p);return p->back->data;
}
- 直接就是队尾节点的数据域
获取队列长度
//获取队列长度
int QueueSize(Queue* p)
{//对传入参数合法性的判断assert(p);//哎呦 这不是我的老朋友计数器吗int count = 0;//好家伙 这不是老伙计遍历指针Queuenode* cur = p->front->next;while (cur) {count++;cur = cur->next;}return count;
}
- 给一个遍历指针,给个计数器,遍历一个就++最后返回count。
判断是否为空队列
//判断是否为空队列
int QueueEmpty(Queue* p)
{//对传入参数合法性的判断assert(p);//俩指针都指向头结点这不就是空队列了return p->front == p->back;
}
- 俩指针都指向头结点这不就是空队列了
队列的销毁
//队列的销毁
void QueueDestory(Queue* p)
{//对传入参数合法性的判断assert(p);//先来一个便利指针Queuenode* cur = p->front->next;while (cur) {//这个队头指针一个个指向下一个节点p->front->next = cur->next;free(cur);cur = p->front->next;}free(p->front);p->back = NULL;p->front = NULL;
}
- 创建一个遍历指针指向第一个节点。
- 来移动头指针,然后释放掉刚刚头指针指向的这个节点。
- 刚刚头指针的下一个节点的地址刚刚被保存了,这块的cur还有tmep的作用。
测试用例
void text() {Queue p;QueueInit(&p);printf("size = %d\n", QueueSize(&p));printf("\n");// 入队列QueuePush(&p, 1);QueuePush(&p, 2);QueuePush(&p, 3);QueuePush(&p, 4);QueuePush(&p, 5);QueuePush(&p, 6);QueuePush(&p, 7);printf("size = %d\n", QueueSize(&p));printf("front = %d\n", QueueFront(&p));printf("back = %d\n", QueueBack(&p));printf("\n");// 出队列QueuePop(&p);printf("size = %d\n", QueueSize(&p));printf("front = %d\n", QueueFront(&p));printf("back = %d\n", QueueBack(&p));printf("\n");QueuePop(&p);QueuePop(&p);QueuePop(&p);QueuePop(&p);QueuePop(&p);printf("size = %d\n", QueueSize(&p));printf("front = %d\n", QueueFront(&p));printf("back = %d\n", QueueBack(&p));printf("\n");QueuePop(&p);QueuePop(&p);printf("size = %d\n", QueueSize(&p));QueueDestory(&p);
}
数据结构 严薇敏 队列 的实现及其使用方法详解相关推荐
- 数据结构 严薇敏 堆 的实现及其使用方法详解
1.堆的概念 将一个关键码的集合K = {k0 , k1,k2,k3--kn-1}把他所有元素按完全二叉树的存储方式放在一个一维数组中,并且满足双亲节点大于孩子节点,或者双亲节点小于孩子节点将根节点最 ...
- 数据结构 严薇敏 栈 的实现及其使用方法详解
目录 1.栈 1.1栈的概念及结构 1.2栈的实现 1.3接口以及实现 Stack.h Stack.c 栈的初始化 入栈 出栈 获取栈顶元素 获取栈中有效元素的个数 检测栈是否为空 栈的销毁 扩容 测 ...
- 数据结构 严薇敏 顺序表的实现(增 删 改)及其使用方法详解
时间复杂度 数据结构 时间复杂度和空间复杂度 目录 1.线性表 2.顺序表 2.1概念及结构 2.2 接口实现 SeqList.h SeqList.c 2.2.1初始化链表以及销毁链表的实现 初始化顺 ...
- c语言栈是什么线性表,数据结构严薇敏——栈的顺序存储(C语言)
栈是限定只能在表尾进行插入和删除操作的线性表. 栈的特点是后进先出. 它的顺序数据结构定义为 typedef struct SQSTACK { ElemType *base; ElemType *to ...
- Mr.J--C语言头函数的建立(附严薇敏《数据结构》线性表代码)
如何正确编写 C 语言头文件和与之相关联的 c 源程序文件 查看此文章需要有一定的C语言编程基础 首先就要了解它们的各自功能.要理解C 文件与头文件(即.h)有什么 不同之处,首先需要弄明白编译器的工 ...
- wringPi 初始化GPIO 为上拉_敏矽微电子Cortex-M0学习笔记04-GPIO详解及应用实例
前面我们已经对敏矽微电子的基于cortex m0内核的ME32F030R8T6的基本功能做了介绍,然后详细讲解了开发环境MDK的安装,pack包的安装,工程的建立及程序的仿真,紧接着讲解了ME32F0 ...
- 六:抽象队列同步器AQS应用之BlockingQueue详解
目录 概要 队列类型 队列数据结构 ArrayBlockingQueue LinkedBlockingQueue DelayQueue BlockingQueue API 多线程生产者-消费者示例 并 ...
- 消息队列的实现原理和ActiveMQ详解
一.链式调用 在我们日常的项目开发过程中,一般各模块或者函数方法之间,都是采用链式调用的方式,为了完成一个整体功能,我们会将其拆分成多个函数(或者子模块),比如模块A调用模块B,模块B调用模块C,模块 ...
- python优先级排序_Python实现优先级队列结构的方法详解
最简单的实现一个队列至少满足2个方法,put和get. 借助最小堆来实现. 这里按"值越大优先级越高"的顺序. #coding=utf-8 from heapq import he ...
最新文章
- MBZUAI大学招生了,Michael Jordan、Raj Reddy等大佬授课
- 还有王法吗?美国联邦调查局开发人脸识别系统,数据源涉及公民隐私
- ITK:索引置换序列
- mysql 重置更新祖级字段
- thinkphp python_ThinkPhp 5.0 服务器搭建问题总结
- 阅读react-redux源码 - 零
- linux下计算目录文件和,统计Linux 中文件和文件夹/目录的数量(示例代码)
- windows和linux没有启动选择,重装Windows后,LILO启动选单不见了,无法进入Linux系统怎么办...
- iis php5.4配置_PHP5.4 + IIS + Win2008 R2 配置
- PHP与Unicode签名(BOM)
- CTP接口封装相关贴---集合
- ooffice为保护计算机,office已检测到此文件存在问题编辑此文件可能会损害您的计算机!...
- Latex学习笔记(十五)特殊符号的插入
- 复合辛普森公式求解定积分 matlab
- 《王者荣耀》伤害计算(数值研究)
- strawberry perl环境安装介绍
- 非常全面的NFS文档(FOR LINUX)
- JavaWeb——Spring 的操作数据库的 DAO模式
- 守护进程--day33
- thinkphp文件上传以及 unable to create temporary file in 警告
热门文章
- 【python】使用pip安装指定版本的模块,卸载、查看、更新包
- isDebugEnabled作用
- 怎么看计算机配件型号,如何看硬件参数
- verilog中tb仿真文件模板
- 第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组
- SM2256K上K9OKGY8S7D开卡成功
- 【大数据分析】Spark的joins研究
- AI in Finance<量化交易人工智能金融投资>(下)
- 2018年算法工程师薪酬报告出炉:平均年薪50.21万,点燃寒冬的一把火
- 《2006_ICPR_Low Resolution Character Recognition by Image Quality Evaluation》阅读笔记