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

news2024/11/16 3:43:43

目录

前言

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.coloradmin.cn/o/1677506.html

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

相关文章

知识图谱开发日志

应用于应用环境的配置.测试.发布 假如你写了一个web,并且测试调试都没有问题 并且,你想发给你的朋友,导师,或者部署到远程云服务器上 那么,你需要配置相同的软件,比如数据库,web服务器,必要的插件,库,etc…但这并不一定能保证软件的正常运行,因为别人可能使用完全不同的操作系统…

Facebook广告运营黑五类怎么投?

哈喽呀&#xff0c;很多小伙伴不知道黑五具体是哪些今天就跟大家来说说&#xff0c;黑五类是指一些擦边的受到限制的产品&#xff0c;指的是药品、医疗器械、丰胸、减肥、增高这五类产品。 黑五类产品可以在哪些平台进行投放&#xff1a; 目前黑五类可以广告投放的跨境电商平台…

第三方组件element-ui

1、创建 选vue2 不要快照 vue2于vue3差异 vue2main。js import Vue from vue import App from ./App.vueVue.config.productionTip falsenew Vue({render: h > h(App), }).$mount(#app)vue3 main.js vue2不能有多个跟组件&#xff08;div&#xff09; 代码&#xff1a;Mo…

ssm教材管理系统

ssm教材管理系统 一、主要技术点 ssm,easypoi(对excel导入导出)&#xff0c;下拉列表二级联动&#xff0c;live-2d看板娘&#xff0c;echartjs图表&#xff0c;图片上传下载。。 二、主要业务逻辑 管理员可以增删改查教材、教材商、入库教材、用户&#xff08;用户包括学生…

2024年京东618红包领取口令是什么?2024年618京东红包活动时间是从什么时候开始到几号结束?

2024年京东618红包活动时间 京东618红包活动时间是从2024年5月28日开始&#xff0c;一直持续到6月18日结束。 2024年京东618红包领取方式 在2024年京东618活动时间内&#xff0c;每天都可以打开手机京东APP&#xff0c;输入框搜索红包领取口令「 天降红包882 」&#xff0c;搜…

Java——对象的打印

当我们运行如下代码&#xff1a; public class Person {String name;String gender;int age;public Person(String name,String gender,int age){this.name name;this.gender gender;this.age age;}public static void main(String[] args){Person person new Person(&quo…

Google I/O 2024 干货全解读:Gemini AI 横空出世,智能未来触手可及!

Google I/O 2024 干货全解读&#xff1a;Gemini AI 横空出世&#xff0c;智能未来触手可及&#xff01; 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》…

从新手到高手,教你如何改造你的广告思维方式!

想要广告震撼人心又让人长时间记住&#xff1f;答案肯定是“创意”二字。广告创意&#xff0c;说白了就是脑洞大开&#xff0c;想法新颖。那些很流行的广告&#xff0c;都是因为背后的想法特别、新颖。做广告啊&#xff0c;就得不停地思考&#xff0c;创新思维是关键。 广告思…

一部手机、一段视频,快速开展自动无人直播获取潜在客户

​​直播已经成为一种全新的营销方式。对于实体门店而言&#xff0c;直播具有吸引潜在客户、提升品牌知名度以及促进销售的巨大潜能。然而&#xff0c;很多门店因缺乏专业的直播设备和人员而无法轻松实现直播。为此&#xff0c;我们隆重介绍一款手机自动直播门店助手&#xff0…

数据治理框架下,如何实现高效且安全的数据提取与分析

一、引言 随着数字化时代的到来&#xff0c;数据已成为企业运营和决策的核心资产。然而&#xff0c;数据的复杂性和多样性也为企业带来了数据提取与分析的挑战。为了实现数据的有效利用&#xff0c;并确保数据的安全性&#xff0c;需要在数据治理框架下构建高效且安全的数据提…

智慧公厕,提升公共厕所管理效率的信息化变革

现代社会中&#xff0c;公共厕所的管理成为一个不可忽视的问题。随着城市化进程的加快&#xff0c;人们对公厕的需求日益增加&#xff0c;但公厕的管理却面临诸多困难。为了解决这一问题&#xff0c;智慧公厕应运而生&#xff0c;通过信息化的变革&#xff0c;提高公厕的管理效…

253 基于matlab的液压位置控制源代码

基于matlab的液压位置控制源代码&#xff0c;有摩擦补偿&#xff0c;利用滑模控制器实现&#xff0c;神经网络逼近。最后实现位置角度和速度的控制。输出控制误差。程序已调通&#xff0c;可直接运行。 253 液压位置控制 滑模控制器 控制误差 - 小红书 (xiaohongshu.com)

springboot引入第三方jar包本地lib并打包

1&#xff1a;在项目根目录创建lib目录并放入第三方lib包 -- project ----lib &#xff08;放在这儿&#xff09; ----src ----target2&#xff1a;pom中引入第三方lib <!-- 引入magus模块 --><dependency><groupId>org.jeecg.msgus</groupId><art…

【源码】2024全新多语言区块链交易所源码/期权交易/申购/币币秒合约交易所

全新ui&#xff0c;更新很多内容&#xff0c;具体看图&#xff0c;全部开源 全新多语言区块链交易所源码/期权交易/申购/币币秒合约交易所 - 吾爱资源网

C++复习 -- 继承

继承基本概念 继承是面向对象编程&#xff08;OOP&#xff09;中的一个核心概念&#xff0c;特别是在C中。它允许一个类&#xff08;称为派生类或子类&#xff09;继承另一个类&#xff08;称为基类或父类&#xff09;的属性和方法。 继承的主要目的是实现代码重用&#xff0…

[启明智显技术分享] 在ESP32环境搭建过程中,如果在VS Code中遇到乱码问题应该怎么解决

前言&#xff1a; 【启明智显】专注于HMI&#xff08;人机交互&#xff09;及AIoT&#xff08;人工智能物联网&#xff09;产品和解决方案的提供商&#xff0c;我们深知彩屏显示方案在现代物联网应用中的重要性。为此&#xff0c;我们一直致力于为客户提供彩屏显示方案相关的技…

Gitlab、Redis、Nacos、Apache Shiro、Gitlab、weblogic相关漏洞

文章目录 一、Gitlab远程代码执行&#xff08;CVE-2021-22205&#xff09;二、Redis主从复制远程命令执行三、Nacos认证绕过漏洞&#xff08;CVE-2021-29441&#xff09;四、Apache Shiro认证绕过漏洞&#xff08;CVE-2020-1957&#xff09;五、Gitlab任意文件读取漏洞&#xf…

(done) NLP+HMM 协作,还有维特比算法

参考视频&#xff1a;https://www.bilibili.com/video/BV1aP4y147gA/?p2&spm_id_frompageDriver&vd_source7a1a0bc74158c6993c7355c5490fc600 &#xff08;这实际上是 “序列标注任务”&#xff09; HMM 的训练和预测如下图 训练过程&#xff1a;我们首先先给出一个语…

【leetcode面试经典150题】-27. 移除元素

88.合并两个有序数组 1 题目介绍1 个人解题思路1.1 解题代码1.2 思路解析 2、分析官方题解2.1 单侧双指针2.2 双侧双指针 1 题目介绍 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外…

【Segment Anything Model】十四:原始SAM模型如何传入多框

之前第二三篇有更新过单点&#xff0c;多点&#xff0c;单框。本篇加上多框输入。 先确定一下目录 新建test_boxes.py文件&#xff0c;复制以下代码 import sys import torch import numpy as np from datetime import datetime import matplotlib.pyplot as plt from Net.se…