队列的实现

学习就像一段长跑,比的不是谁跑得快,而是谁更能坚持!!


 1 队列的概念及结构

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

 和栈不同的是,队列的出队顺序是唯一的!

2 队列的实现

分析

有两种实现队列的方式:数组链表。链表可以用单链表也可以用双链表。

使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率很低!
数组实现:效率低!!

链表实现:单链表更合适!!

思考一个问题,需要带哨兵位的头节点吗?

  • 其实都可以,不带也可以,可以不用判断直接尾插,但是如果带了哨兵位的头节点,要malloc,最后也要free释放空间。

因为队列我们只需要入队(尾插)和出队(头删),单链表都可以实现,不需要使用双链表。但是我们要想,我们要怎么分清队头和队尾呢?所以我们在尾插头删的时候:

  • 需要ptail指针维护队列最后一个元素
  • 需要phead指针维护队列第一个元素

那么这个时候实现起来就需要用到二级指针了。很不方便。

那么我们怎么解决这个问题呢?(不用二级指针的等效替换方法)

①带哨兵位的头节点。②返回值。③可以考虑用一个结构体封装起来。

这里我们用结构体。 

代码实现

Test.c

#define _CRT_SECURE_NO_WARNINGS 1#include"Queue.h"int main()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);printf("%d ", QueueFront(&q));QueuePop(&q);printf("%d ", QueueFront(&q));QueuePop(&q);QueuePush(&q, 4);QueuePush(&q, 5);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);return 0;
}

函数声明Queue.h

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef int QDataType;//创建队列节点
typedef struct QueueNode
{QDataType val;struct QueueNode* next;
}QNode;//创建维护队列的指针
typedef struct Queue
{QNode* phead;QNode* ptail;int size;//原本是需要遍历的,写在结构体里可以很好的是时间复杂度由O(N)变为O(1)
}Queue;//初始化
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);

函数实现Queue.c 

初始化QueueInit
void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}
空间释放QueueDestroy
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
入队列QueuePush

这里需要创建一个节点

void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->val = x;newnode->next = NULL;if (pq->ptail == NULL){pq->ptail = pq->phead = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
出队列QueuePop

要注意两种情况

  • 空链表
  • 只有一个元素(ptail野指针的情况,要进行判断置空)
void QueuePop(Queue* pq)
{assert(pq);//链表不为空assert(pq->phead);QNode* del = pq->phead;pq->phead = pq->phead->next;free(del);del = NULL;//链表中只有一个元素,删完以后为空if (pq->phead == NULL)pq->ptail = NULL;pq->size--;
}
队头元素QueueFront
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}
队尾元素QueueBack
QDataType QueueBack(Queue* pq)
{assert(pq); assert(pq->ptail);return pq->ptail->val;
}
判断队列是否为空QueueEmpty
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}
队列元素个数QueueSize
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}

Queue.c总代码

#define _CRT_SECURE_NO_WARNINGS 1#include"Queue.h"void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->val = x;newnode->next = NULL;if (pq->ptail == NULL){pq->ptail = pq->phead = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);// assert(pq->phead);QNode* del = pq->phead;pq->phead = pq->phead->next;free(del);del = NULL;if (pq->phead == NULL)pq->ptail = NULL;pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);// assert(pq->phead);return pq->phead->val;
}QDataType QueueBack(Queue* pq)
{assert(pq); assert(pq->ptail);return pq->ptail->val;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}

以上就是用单链表实现队列的代码实现。

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

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

相关文章

外网访问内网服务器使用教程

如何在任何地方都能访问自己家里的笔记本上的应用&#xff1f;如何让局域网的服务器可以被任何地方访问到&#xff1f;有很多类似的需求&#xff0c;我们可以统一用一个解决方案&#xff1a;内网穿透。内网穿透的工具及方式有很多&#xff0c;如Ngrok、Ssh、autossh、Natapp、F…

linux具体命令(一)

1. cd CD命令是Linux和类Unix操作系统中非常常用的一个命令&#xff0c;它的全称是“change directory”&#xff0c;用于改变当前的工作目录。用户可以通过这个命令进入到不同的目录中&#xff0c;进行文件操作或是执行其他任务。 以下是CD命令的一些基本用法&#xff1a; 进…

特殊进程之守护进程

文章目录 1、守护进程的概念2、如何查看守护进程3、编写守护进程的步骤3.1 创建子进程&#xff0c;父进程退出3.2 在子进程中创建新会话3.3 改变当前工作目录3.4 重设文件权限掩码3.5 关闭不需要的文件描述符3.6 某些特殊的守护进程打开/dev/null 4、守护进程代码示例 1、守护进…

[UNILM]论文实现:Unified Language Model Pre-training for Natural Language.........

文章目录 一、完整代码二、论文解读2.1 介绍2.2 架构2.3 输入端2.4 结果 三、过程实现四、整体总结 论文&#xff1a;Unified Language Model Pre-training for Natural Language Understanding and Generation 作者&#xff1a;Li Dong, Nan Yang, Wenhui Wang, Furu Wei, Xia…

js new 原理

mdn new new 调用函数时&#xff0c;该函数将被用作构造函数 类只能用 new 运算符实例化 不使用 new 调用一个类将抛出 TypeError。 过程 new Foo(…) 执行时&#xff1a; 创建一个空的简单 JavaScript 对象。 为方便起见&#xff0c;我们称之为 newInstance。 如果构造函数…

华为OD机试真题-执行任务赚积分-2023年OD统一考试(C卷)

题目描述: 现有N个任务需要处理,同一时间只能处理一个任务,处理每个任务所需要的时间固定为1。 每个任务都有最晚处理时间限制和积分值,在最晚处理时间点之前处理完成任务才可获得对应的积分奖励。 可用于处理任务的时间有限,请问在有限的时间内,可获得的最多积分。 输入…

《LeetCode力扣练习》代码随想录——字符串(替换数字---Java)

《LeetCode力扣练习》代码随想录——字符串&#xff08;替换数字—Java&#xff09; 刷题思路来源于 代码随想录 54. 替换数字 受制于语言限制&#xff0c;很普通的解法 import java.util.Scanner; class Main {public static void main(String[] args) {Scanner innew Scanner…

MyBatis--07--启动过程分析、SqlSession安全问题、拦截器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 谈谈MyBatis的启动过程具体的操作过程如下&#xff1a;实现测试类,并测试SqlSessionFactorySqlSession SqlSession有数据安全问题?在MyBatis中&#xff0c;SqlSess…

vuex如何存储数据、获取数据、以及数据的持久化

前提必须已经在vue中安装了vuex插件不然无法使用&#xff0c;不知道怎么创建vue和安装vuex的可以看这个视频&#xff0c;node.js版本最好16以上不然可能会安装失败&#xff1a;30分钟学会Vue之VueRouter&Vuex 趁着暑假掌握一门技能 大学生前端实习毕业设计必备技能_哔哩哔哩…

好代码资源网整站打包代码(包含了最新数据),集成了深度二开的ripro主题,非常适合做资源网站创业用

好代码资源网是基于wordpress开发的一个资源分享类网站&#xff0c;在开发者圈子里还算小有名气&#xff0c;这里分享婴整站打包代码&#xff08;包含了最新数据&#xff09;。网站本身集成了深度二开的ripro主题&#xff0c;非常适合做资源网站创业用。 资源下载类网站目前还…

Button背景颜色改不了,一直是默认的紫色

使用android.widget.Button <android.widget.Buttonandroid:layout_width"wrap_content"android:layout_height"wrap_content"android:onClick"doClick"android:text"这是一个按钮"android:textColor"color/black"androi…

kubesphere安装后启用DevOps

官方文档&#xff1a;KubeSphere DevOps 系统 1、集群管理---定制资源定义 进入目录&#xff1a;集群管理---定制资源定义搜索&#xff1a;clusterconfiguration 点击 ks-installer 右侧的 &#xff0c;选择编辑 YAML 在该 YAML 文件中&#xff0c;搜索 devops&#xff0c;…

力扣98. 验证二叉搜索树

深度优先遍历 思路&#xff1a; 根据二叉搜索树特性&#xff0c;通过中序遍历得到有序序列&#xff0c;验证序列是否有序来判断&#xff1b;中序遍历使用栈通过深度优先遍历&#xff1b; /*** Definition for a binary tree node.* struct TreeNode {* int val;* Tre…

No CUDA GPUs are available

文章目录 前言尝试方法一、尝试方法一二、尝试方法二 总结 前言 之前用服务器跑的时候&#xff0c;发现是可以跑的。但当有其他人一同使用的时候&#xff0c;就会抛出&#xff1a;No CUDA GPUs are available&#xff0c;这个时候我尝试了以下两种方式解决&#xff0c;后面终于…

一到冬天,助听器出现声音小、无声、时有时无……

冬天是一个寒冷干燥的季节&#xff0c;对于助听器的使用者来说&#xff0c;也是一个需要特别注意保养的季节。助听器是高精密的电子产品&#xff0c;如果不注意保养&#xff0c;可能会出现声音小、无声、时有时无等故障&#xff0c;影响听力康复的效果。那么&#xff0c;冬天我…

C++中string类的使用

目录 一.string类 1.1为什么学习string类&#xff1f; 1.2.标准库中的string类 二.string对象的元素访问 2.1.1使用operator[]与at实现访问 2.1.2正向迭代器访问 2.1.3反向迭代器访问 2.1.4const正向迭代器&#xff08;不能修改&#xff09; 2.1.5const反向迭代器&#…

计算机网络知识点合集【王道计算机考研】

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

维护真实时间:应对系统时间篡改的技巧

引言 在App使用中&#xff0c;由于系统时间用户可以随意更改&#xff0c;在某些特殊情况下会导致获取到的系统时间不正确问题。本篇代码使用dart语言进行相关描述。 1.问题分析&#xff1a; 手机系统时间 ≠ 真实时间&#xff0c;当我们做一些需要对时间精度和准确性要求较高的…

SQL命令---修改数据库的编码

介绍 使用sql命令修改数据库的编码&#xff0c;修改为utf8mb4编码。 命令 alter database 数据库名称 default character set utf8mb4;

垃圾收集算法和各种垃圾收集器的实现

深入理解Jvm虚拟机第三章 二、对象已死&#xff1f;3.2.1 引用计数算法3.2.2 可达性分析算法3.2.3 再谈引用3.2.4 生存还是死亡3.2.5 回收方法区 三、垃圾收集算法3.3.1 分代收集理论3.3.2 标记-清除算法3.3.3 标记-复制算法3.3.4 标记-整理算法 四、HotSpot的算法细节实现3.4.…