数据结构与算法学习笔记十---链队列的表示和实现(C++)

目录

前言

1.队列的概念

2.队列的表示和实现

1.定义

2.初始化

​编辑

3.销毁队列

4.清空队列

5.队列判空

6.队列长度

7.获取队头元素

8.入队

9.出队

10.遍历

11.完整代码


前言

    这篇博客主要讲的是对队列的链式存储。

1.队列的概念

        队列是一种访问受限的线性表。仅允许在表的一端进行插入操作,在表的另一端进行删除操作。和日常生活中的排队是一致的,最先进入队列的元素最早离开。插入的一端称为队头(front),删除的一端称为队尾(rear)。

        队列的示意图如下:

        图1.队列的示意图

2.队列的表示和实现

1.定义

        我们使用指针我们使用指向结点元素的指针分别表示队列的队头和队尾。

typedef int ElemType;
typedef struct QNode{ElemType data;struct QNode * next;
}QNode,*QueuePtr;typedef struct {QueuePtr  front,rear;
}LinkQueue;

2.初始化

        链队列的初始化是构造一个只有一个头结点的空队,使队头和队尾指针指向次节点,并将节点的指针置为NULL。如下图2所示。

        图2.链队列的操作示意图

队列的初始化代码如下:

//初始化
Status initLinkQueue(LinkQueue *queue) {queue->front = queue->rear = new QNode;if (!queue->front) {return 0; // 内存分配失败}queue->front->next = NULL;return 1;
}

3.销毁队列

        为链队列增加销毁方法相对简单,只需释放链表中的所有节点即可。

// 销毁队列
Status destroyQueue(LinkQueue *queue) {QueuePtr p, q;p = queue->front;while (p) {q = p;p = p->next;delete q;}queue->front = queue->rear = NULL;return 1;
}

4.清空队列

        清空队列的方法类似于销毁队列,但是不释放头结点。可以通过循环释放除头结点外的所有节点,并将头结点的 frontrear 指针重新指向头结点。

// 清空队列
Status clearQueue(LinkQueue *queue) {QueuePtr p, q;p = queue->front->next; // 从头结点的下一个节点开始遍历while (p) {q = p;p = p->next;delete q;}queue->front->next = NULL; // 确保头结点的 next 指针为空,即队列为空// 注意:这里不释放 queue->front,因为它是队列的永久头节点queue->rear = queue->front; // 重新设置队尾指针return 1;
}

5.队列判空

        当对头和队尾相同的时候,队列为空。

//判空
Status isEmpty(LinkQueue *queue) {return queue->front->next == NULL; // 如果头指针的下一个节点为空,则队列为空
}

6.队列长度

        可以通过遍历队列中的元素来计算队列的长度。

// 求队列长度
int queueLength(LinkQueue *queue) {int length = 0;QueuePtr p = queue->front->next; // 从头结点的下一个节点开始遍历while (p) {length++;p = p->next;}return length;
}

7.获取队头元素

              获取链队列头元素的时候,首先要判断链队列是否是空队列,如果队列为空,不操作;否则,获取队列的头结点的下一个元素即可(因为我们这里用到了头结点,头结点的数据域是不可用使用的)。

//获取队列头元素
Status getHead(LinkQueue *queue, ElemType *e) {if (queue->front == queue->rear) {return 0; // 队列为空}*e = queue->front->next->data;return 1;
}

8.入队

        入队的过程其实是生成一个新的节点,并且修改尾指针,并且把尾指针设置称为新的节点。

//入队
Status enQueue(LinkQueue *queue, ElemType e) {QueuePtr p = new QNode;if (!p) {return 0; // 内存分配失败}p->data = e;p->next = NULL;queue->rear->next = p;queue->rear = p;return 1;
}

9.出队

        连队列的出队首先是判断链队列是否为空,如果为空,则不操作;否则取出表头元素,修改头指针。

//出队
Status deQueue(LinkQueue *queue, ElemType *e) {if (queue->front == queue->rear) {return 0; // 队列为空}QueuePtr p = queue->front->next;*e = p->data;queue->front->next = p->next;if (queue->rear == p) {queue->rear = queue->front; // 如果出队后队列为空,修改队尾指针}delete p;return 1;
}

10.遍历

        这里当队头和队尾相同的时候,链队列即为空队列。

// 遍历队列
void traverseLinkQueue(LinkQueue *queue) {if (isEmpty(queue)) {cout << "Queue is empty." << endl;return;}QueuePtr p = queue->front->next; // 从头结点的下一个节点开始遍历while (p) {cout << p->data << " "; // 输出队列中的元素p = p->next;}cout << endl; // 输出完毕后换行
}

11.完整代码

#include <iostream>
using namespace std;typedef int ElemType;
typedef int Status;
typedef struct QNode {ElemType data;struct QNode *next;
} QNode, *QueuePtr;typedef struct {QueuePtr  front, rear;
} LinkQueue;//初始化
Status initLinkQueue(LinkQueue *queue) {queue->front = queue->rear = new QNode;if (!queue->front) {return 0; // 内存分配失败}queue->front->next = NULL;return 1;
}
// 清空队列
Status clearQueue(LinkQueue *queue) {QueuePtr p, q;p = queue->front->next; // 从头结点的下一个节点开始遍历while (p) {q = p;p = p->next;delete q;}queue->front->next = NULL; // 确保头结点的 next 指针为空,即队列为空// 注意:这里不释放 queue->front,因为它是队列的永久头节点queue->rear = queue->front; // 重新设置队尾指针return 1;
}//判空
Status isEmpty(LinkQueue *queue) {return queue->front->next == NULL; // 如果头指针的下一个节点为空,则队列为空
}
// 求队列长度
int queueLength(LinkQueue *queue) {int length = 0;QueuePtr p = queue->front->next; // 从头结点的下一个节点开始遍历while (p) {length++;p = p->next;}return length;
}//入队
Status enQueue(LinkQueue *queue, ElemType e) {QueuePtr p = new QNode;if (!p) {return 0; // 内存分配失败}p->data = e;p->next = NULL;queue->rear->next = p;queue->rear = p;return 1;
}//出队
Status deQueue(LinkQueue *queue, ElemType *e) {if (queue->front == queue->rear) {return 0; // 队列为空}QueuePtr p = queue->front->next;*e = p->data;queue->front->next = p->next;if (queue->rear == p) {queue->rear = queue->front; // 如果出队后队列为空,修改队尾指针}delete p;return 1;
}//获取队列头元素
Status getHead(LinkQueue *queue, ElemType *e) {if (queue->front == queue->rear) {return 0; // 队列为空}*e = queue->front->next->data;return 1;
}
// 遍历队列
void traverseLinkQueue(LinkQueue *queue) {if (isEmpty(queue)) {cout << "Queue is empty." << endl;return;}QueuePtr p = queue->front->next; // 从头结点的下一个节点开始遍历while (p) {cout << p->data << " "; // 输出队列中的元素p = p->next;}cout << endl; // 输出完毕后换行
}int main(int argc, const char * argv[]) {LinkQueue queue;cout<<"链队列初始化中..."<<endl;if (initLinkQueue(&queue)) {cout<<"链队列初始化成功"<<endl;}cout<<"链队列判空和长度..."<<endl;cout<<"队列长度:"<<queueLength(&queue)<<endl;if (isEmpty(&queue)) {cout<<"队列为空"<<endl;}// 入队enQueue(&queue, 1);enQueue(&queue, 2);enQueue(&queue, 3);traverseLinkQueue(&queue);ElemType head;if (getHead(&queue, &head)) {cout<<"队头指针:"<<head<<endl;}cout<<"出队测试......"<<endl;int element;if (deQueue(&queue, &element)) {cout<<"出队列成功,出队元素:"<<element<<endl;}cout<<"出队之后的队列......"<<endl;traverseLinkQueue(&queue);cout<<"清空队列......"<<endl;if (clearQueue(&queue)) {cout<<"队列清空成功,队列长度:"<<queueLength(&queue)<<endl;}// 出队并打印ElemType e;while (!isEmpty(&queue)) {deQueue(&queue, &e);cout << e << " ";}cout << endl;return 0;
}

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

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

相关文章

在VMware安装Androidx86_64系统要点

上篇使用VirtualBox安装过Androidx86_64系统&#xff0c;尝试了没有蓝牙共享的好方法。本篇记录下使用Vmware虚机安装改系统&#xff0c;并使用蓝牙共享功能。 1.准备材料 本篇安装环境是安装Window10_64位系统。需要下载好Vmware安装包&#xff0c;VMWare版本&#xff1a;VMw…

【AI Engine Series】[AI Engine Series 3 - Introduction to AI Engine kernels

AI Engine Series 3 - Introduction to AI Engine kernels 双击summary 进入analyzer AI Engine Series 6 - Analyzing AI Engine compilation results in Vitis Analyzer (2022.1 update) [connectivity] stream_connectM_AXIS_ADDER:ai_engine_0.DataIn1 stream_connecta…

Java应用程序的本地内存跟踪分析

本文将讨论本机内存跟踪 (NMT)&#xff0c;我们可以使用它来隔离在 VM 级别增长的任何异常内存。 1.什么是本机内存&#xff1f; 本机内存是指计算机系统上运行的应用程序或程序可直接访问的内存空间。它是程序在执行期间存储和操作数据的内存区域。本机内存不同于托管内存&a…

在不同的应用系统创建Python虚拟环境

在不同的应用系统创建Python虚拟环境 在Linux上创建Python虚拟环境 一、在Ubuntu上创建Python虚拟环境 可以通过使用virtualenv工具来完成。下面是创建Python虚拟环境的步骤&#xff1a; 首先确保已经安装了python3-venv包&#xff08;如果没有安装&#xff0c;则需要运行命…

docker 修改运行容器环境变量

文章目录 前言第一步&#xff1a;查看Docker Root目录第二步&#xff1a;查到容器的长id&#xff08;container id&#xff09;第三步&#xff1a;停止容器第四步&#xff1a;编辑修改环境变量env第五步&#xff1a;重载服务的配置文件第六步&#xff1a;重启docker 总结 前言 …

webpack生成模块关系依赖图示例:查看构建产物的组成部分 依赖关系图

npm i -D webpack-bundle-analyzer core-js babel-loaderwebpack.config.js const BundleAnalyzerPlugin require(webpack-bundle-analyzer).BundleAnalyzerPlugin; module.exports {entry: ./src/index.js,output: {filename: main.js,},// mode: production, // 或者 produ…

如何在 Windows 11/10 中恢复已删除的分区

在将重要数据存储在计算机上之前&#xff0c;许多用户会创建分区以更好地组织和管理他们的文件。此分区可以在内部硬盘驱动器或外部存储设备上创建。但是&#xff0c;有时可能会意外删除分区。如果发生这种情况&#xff0c;您可能想知道是否可以在不丢失任何信息的情况下恢复已…

Kubernetes二进制(单master)部署

文章目录 Kubernetes二进制&#xff08;单master&#xff09;部署一、常见的K8S部署方式1. Minikube2. Kubeadmin3. 二进制安装部署4. 小结 二、K8S单&#xff08;Master&#xff09;节点二进制部署1. 环境准备1.1 服务器配置1.2 关闭防火墙1.3 修改主机名1.4 关闭swap1.5 在/e…

AI应用案例:律师服务质量评价

利用微调后的模型对律师的服务质量进行评价是一种高效且客观的方法。首先&#xff0c;我们需要一个预先训练好的模型作为基础&#xff0c;这个模型可能已经具备了处理文本或类似数据的能力。然后&#xff0c;针对律师服务质量的特定需求&#xff0c;我们对模型进行微调&#xf…

Milvus 快速入门

引言 在本篇文章中&#xff0c;我们将介绍 Milvus 的基本概念&#xff0c;并通过一个简单的示例展示如何在 Milvus 中创建集合、插入向量和执行搜索。最后&#xff0c;我们将概览 Milvus 提供的 API。 一、基本概念 1.1 集合 (Collection) 在 Milvus 中&#xff0c;集合类似…

如何在华企盾DSC数据防泄密系统中自定义加密级别?

在华企盾DSC系统中&#xff0c;你可以通过密级权限功能来自定义加密文件的密级高低。每个终端下都有严格的受限范围&#xff0c;文件密级的高低将直接决定该终端是否拥有打开该加密文件的权利。如果不在权限范围内&#xff0c;则无法打开该加密文件。详细步骤如下&#xff1a; …

守护长者安全,平安养老险携手福海街道开展防灾减灾活动

在构建和谐社会、倡导人文关怀的当下&#xff0c;平安养老险以高度的社会责任感和深厚的人文情怀&#xff0c;持续关注老年人的健康与安全。在今年“5.12防灾减灾日”来临之际&#xff0c;平安养老险深圳分公司积极响应倡议&#xff0c;于5月10日携手福海街道举办了在福海街道举…