数据结构之链式队列的实现操作(C语言附详细代码与关键代码详解)

2023-05-16

目录

一,关于链式队列程序编写的简要说明

二,linkqueue.h头文件

三,关键函数代码与详解

1.创建空的链式队列

2.入队

3.出队

4.销毁链式队列

四,linkqueue.c文件详细代码


一,关于链式队列程序编写的简要说明

    学习链式队列之前,我们已经详细了解了链式表和顺序队列,链式队列的程序编写方式正好是结合了链式表和顺序队列的特点;

    由“链式”我们可知队列中的每一个节点一定有一个数据域data和一个指针域next,队列中节点和节点之间通过指针域进行连接,并且还包含一个数据域为空的头节点;

    由“队列”可知,队列中包含一个头指针front和一个尾指针rear,分别指向头节点和尾节点;除此之外,还需要一个长度变量len,用来计算队列的长度。

    以上就是链式队列中的结构体内需要定义的成员变量。

二,linkqueue.h头文件

    头文件中需要定义两个结构体,一个是包含了节点中数据域和指针域的结构体"link_t",一个是包含了头指针front,尾指针rear和队列长度len的结构体"queue_t"。

    头指针和尾指针的数据类型必须和节点的数据类型相同,这样才能指向节点。

#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_

//队列节点结构体
typedef int datatype;
typedef struct link_mode
{
    datatype data;
    struct link_node *next;
}link_t;
//描述队列节点信息的结构体
typedef struct 
{
    link_t *front;
    link_t *rear;
    int len;
}queue_t;

//1.创建一个空的链式队列
queue_t *CreateQueue(void);
//2.入队
int IntoQueue(queue_t *p,datatype data);
//3.出队
datatype OutQueue(queue_t *p);
//4.判断是否为空
int isEpQueue(queue_t *p);
//5.计算队列长度
int LengthQueue(queue_t *p);
//6.清空队列
int ClearQueue(queue_t *p);
//7.销毁队列
void DestoryQueue(queue_t **p);
#endif

三,关键函数代码与详解

1.创建空的链式队列

    首先需要先开辟包含头指针和尾指针的堆区空间,后面我们才能让它们指向创建的空的头节点,

创建头节点后,将头节点的指针域指向NULL,表示队列为空,最后将队列长度赋值为0。

//1.创建一个空的链式队列
queue_t *CreateQueue(void)
{
    //1.创建头尾指针的内存空间
    queue_t *p = (queue_t *)malloc(sizeof(queue_t));
    if(NULL == p)
    {
        printf("CreateQueue fail\n");
        return NULL;
    }
    //2.创建头节点,并让头尾指针指向它
    p->front=p->rear=(link_t *)malloc(sizeof(link_t));
    if(p->front == NULL)
    {
        printf("malloc head node fail\n");
        return NULL;
    }
    //3.初始化头节点,指针域指向空
    p->front->next = NULL;
    //4.初始化长度
    p->len = 0;
    return p;
}

2.入队

    入队时,也就是向队尾插入数据时,我们要新开辟一个节点空间,并对其进行初始化(赋指定值,指向NULL),每插入一个数据,尾指针的指向就要发生变化,在新节点插入之前,当前尾节点的指针域要指向新节点,然后再将尾指针指向新节点。

//2.入队
int IntoQueue(queue_t *p,datatype data)
{
    //1.开辟新节点内存空间
    link_t *pnew = (link_t *)malloc(sizeof(link_t));
    if(NULL == pnew)
    {
        printf("malloc pnew fail\n");
        return -1;
    }
    //2.初始化新节点
    pnew->data = data;
    pnew->next = NULL;
    //3.当前尾节点指向的节点指针域指向新节点
    p->rear->next = pnew;
    //4.尾节点向后移动,移动到新节点的位置,队列长度加一
    p->rear = pnew;
    p->len++;
    return 0;
}

3.出队

    链式队列的数据出队,就是将队首节点(不是头节点)的数据输出,并将当前的头节点释放;

    首先需要定义一个保存头节点的指针pdel,将该指针pdel指向队列当前的头节点A;然后将头指针指向头节点的下一个节点B,我们要输出的就是头指针现在指向的节点B的数据,要释放的就是头节点A;

    为什么要释放头节点A?为什么释放了头节点A下一个节点B就是新的头节点了呢,因为头指针指向的是要输出数据的节点B,头节点A被释放后,我们还需要找一个节点作为头节点,循环上述操作,很容易就可以看出节点B就是新的头节点,下一个数据输出时,要释放的就是节点B了。

//3.出队
datatype OutQueue(queue_t *p)
{
    //1.判断队列是否为空
    if(isEpQueue(p))
    {
        printf("out fail\n");
        return -1;
    }
    //2,定义一个临时的指向删除节点的指针
    link_t *pdel = NULL;
    //3.pdel指向头指针指向的节点
    pdel = p->front;
    //4.头指针指向下一个节点,将下一个节点作为头节点
    p->front = pdel->next;
    //5.释放临时指针指向的节点,队列长度减一
    free(pdel);
    pdel = NULL;
    p->len--;
    //6.最后返回的是头指针指向的节点的数据
    return p->front->data;
}

4.销毁链式队列

    销毁队列,就是对队列的内存进行操作,所以需要地址传递,对主函数中的队列的内容进行修改;

    首先需要将队列中的数据全部出队,只留下一个头节点;

    然后将头节点中的节点内存空间进行释放;

    然后再将保存了头指针,尾指针和队列长度的内存空间进行释放。

//7.销毁队列
void DestoryQueue(queue_t **p)
{
    ClearQueue(*p);
    free((*p)->front);
    free(*p);
    *p = NULL;
}

四,linkqueue.c文件详细代码

#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"

//1.创建一个空的链式队列
queue_t *CreateQueue(void)
{
    //1.创建头尾指针的内存空间
    queue_t *p = (queue_t *)malloc(sizeof(queue_t));
    if(NULL == p)
    {
        printf("CreateQueue fail\n");
        return NULL;
    }
    //2.创建头节点,并让头尾指针指向它
    p->front=p->rear=(link_t *)malloc(sizeof(link_t));
    if(p->front == NULL)
    {
        printf("malloc head node fail\n");
        return NULL;
    }
    //3.初始化头节点,指针域指向空
    p->front->next = NULL;
    //4.初始化长度
    p->len = 0;
    return p;
}
//2.入队
int IntoQueue(queue_t *p,datatype data)
{
    //1.开辟新节点内存空间
    link_t *pnew = (link_t *)malloc(sizeof(link_t));
    if(NULL == pnew)
    {
        printf("malloc pnew fail\n");
        return -1;
    }
    //2.初始化新节点
    pnew->data = data;
    pnew->next = NULL;
    //3.当前尾节点指向的节点指针域指向新节点
    p->rear->next = pnew;
    //4.尾节点向后移动,移动到新节点的位置,队列长度加一
    p->rear = pnew;
    p->len++;
    return 0;
}
//3.出队
datatype OutQueue(queue_t *p)
{
    //1.判断队列是否为空
    if(isEpQueue(p))
    {
        printf("out fail\n");
        return -1;
    }
    //2,定义一个临时的指向删除节点的指针
    link_t *pdel = NULL;
    //3.pdel指向头指针指向的节点
    pdel = p->front;
    //4.头指针指向下一个节点,将下一个节点作为头节点
    p->front = pdel->next;
    //5.释放临时指针指向的节点,队列长度减一
    free(pdel);
    pdel = NULL;
    p->len--;
    //6.最后返回的是头指针指向的节点的数据
    return p->front->data;
}
//4.判断是否为空
int isEpQueue(queue_t *p)
{
    return p->front == p->rear;
}
//5.计算队列长度
int LengthQueue(queue_t *p)
{
    printf("当前队列长度为%d\n",p->len);
    return 0;
}
//6.清空队列
int ClearQueue(queue_t *p)
{
    while(!isEpQueue(p))
    {
        for(int i = 0;i < p->len;i++)
        {
            OutQueue(p);
        }
    }
    return 0;
}
//7.销毁队列
void DestoryQueue(queue_t **p)
{
    ClearQueue(*p);
    free((*p)->front);
    free(*p);
    *p = NULL;
}

如果本文中存在代码逻辑,代码完善,解释不通或不清楚的错误,还请批评指正。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构之链式队列的实现操作(C语言附详细代码与关键代码详解) 的相关文章

  • Git上fork后的代码仓库如何与原仓库进行同步

    https blog csdn net wakarimasu article details 109152932 问题场景 xff1a 最近公司项目组不允许个人在远程仓库建分支 xff0c 要求每个人fork一个仓库 xff0c 以后就在自
  • Postman安装与入门简单教程

    在测试技术中 xff0c 接口测试是最基础 最重要 xff0c 也是收益最高的测试技术 xff0c 作为接口测试工具中的No 1 xff0c 一起来看看Postman是怎么入门的吧 目录 1 安装Postman2 注册Postman账号并登
  • 使用 Intel RealSense 采集图片并制作机器视觉数据集

    本文章主要涉及以下工作 xff1a xff08 1 xff09 讲述如何使用 Intel RealSense 相机采集RGB图像 深度图像 伪彩色化的深度图像以及 npy 格式保存的深度数据 xff08 2 xff09 采集到的图像可适用于
  • Postman 使用教程 - 手把手教你 API 接口测试

    Postman 教程目录 API 是什么 xff1f Postman 是什么 xff1f 一 如何安装 Postman二 API 模拟工具 GoRest三 用 Postman 发出第一个 GET 请求 1 GET 请求基本操作2 带参数的
  • Socket编程(C语言实现)——TCP协议(网络间通信AF_INET)的流式(SOCK_STREAM)+报式(SOCK_DGRAM)传输

    Socket编程 目前较为流行的网络编程模型是客户机 服务器通信模式 客户进程向服务器进程发出要求某种服务的请求 xff0c 服务器进程响应该请求 如图所示 xff0c 通常 xff0c 一个服务器进程会同时为多个客户端进程服务 xff0c
  • jQuery05插件

    一 自定义插件 1 extend 类方法 1 1对象继承 xff1a extend 对象1 xff0c 对象2 1 2 扩展jQuery类方法 extend 方法名 function xff08 xff09 方法体 getMax funct
  • JavaWeb01(web环境的搭建)

    一 JDK开发工具包 1 下载和安装jdk xff1a https www oracle com index html 2 配置环境变量 JAVA HOME JDK的安装目录 path JAVA HOME bin CLASSPATH xff
  • MySql安装与使用

    今天给大家分享的是关于mysql的安装以及使用 目录 一 mysql安装步骤 二 mysql使用 一 mysql安装步骤 1 首先我们需要下载一个mysql的压缩包 xff0c 进行解压 2 接下来改变my ini文件 修改mysql安装路
  • Shiro认证及加盐加密

    目录 今天的知识是与上次所分享的知识相关联的 xff0c 在Shiro入门的基础进行编写 xff0c 上次之前的数据是死数据 放在Shiro ini 而这次是活数据 xff0c 可以连接到数据库 xff0c 运用域Relam知识 同时出于维
  • 快速掌握Nginx部署前端项目(从Nginx安装配置及部署都非常详细哦!)

    前言 xff1a 之前在Linux系统中部署了后端项目 xff0c 今天继续来给大家分享如何部署前端项目 涉及到了Nginx的简单介绍以及Nginx如何安装及配置并且能够部署前端项目 Nginx是一个轻量级的反向代理web服务器 xff0c
  • I2C协议要点总结

    I2C协议要点总结 https baijiahao baidu com s id 61 1747946282739071669 amp wfr 61 spider amp for 61 pc 一文看懂I2C协议 https zhuanlan
  • Docker数据卷&&自定义Docker镜像

    目录 宿主机与容器之间的文件拷贝 引言 xff1a 利用MySQL镜像安装MySQL服务 从容器中拷贝文件到宿主机 从宿主机拷贝文件到容器 数据卷 数据卷容器 Dockerfile自定义镜像 自定义tomcat8 xff08 熟悉几乎所有的
  • Docker自定义jdk镜像与上传阿里云

    目录 自定义jdk镜像 制作jdk8 v1 0镜像 alpine制作jdk镜像 alpine简介 基于Alpine制作jdk镜像 Alpine制作jre镜像 Docker镜像上传至阿里云 由于官方没有提供jdk xff0c 所以需要自定义j
  • OAuth2(三)

    首先把项目在本地运行起来 注意redis的配置 在地址栏输入 自动跳断点 界面截图
  • 微服务项目框架及多模块开发

    目录 项目简介 项目模式 技术栈 项目架构图 模块 案例演示 主模块 zmall common子模块 zmall user子模块 项目简介 项目模式 电商模式 xff1a 市面上有5种常见的电商模式 xff0c B2B B2C C2B C2
  • Mybatis与微服务注册

    目录 一 SpringBoot整合MybatisPlus 创建自动生成代码子模块 创建商品服务子模块 二 SpringBoot整合Freeamarker 三 SpringBoot整合微服务 amp gateway amp nginx 整合微
  • 呜呼小习题集

    在C语言中exit函数和return有相同的执行效果 xff0c 都是退出当前的函数 xff08 错 xff09 解析 xff1a 1 xff09 return是语言级别的 xff0c 它表示了调用堆栈的返回 xff1b return 是当
  • Ubuntu系统d435i相机驱动与realsense-ros安装

    安装Realsense SDK xff08 如仅仅在ROS中使用相机 xff0c 该步骤可有可无 xff0c 直接进行第二步ROS包的安装即可 xff09 下载安装包 打开终端 xff0c 运行命令 xff1a git clone http
  • 485通讯接受多个传感器信号发生冲突

    一共12个传感器通过485直接接到威纶通屏幕上 xff0c 通讯时有一个温度传感器和两个压力传感器信号会发生冲突 xff0c 温度传感器接通后 xff0c 两个压力传感器在屏幕上数值就不显示 xff0c 不接通的话 xff0c 就会显示 x

随机推荐