【数据结构】 链队列的基本操作 (C语言版)

news2024/11/17 0:07:26

目录

一、链队列

1、链栈的定义:

2、链栈的优缺点:

二、链队列的基本操作算法(C语言)    

1、宏定义

  2、创建结构体

3、链栈的初始化 

4、链队列的入队 

5、链队列的出队

6、取链队列的对头元素

7、链队列的销毁

8、链队列的清空

9、判断链队列是否为空

10、求队列长度

 11、遍历队列元素

三、链队列的基本操作完整代码(C语言)

  四、运行结果


一、链队列

1、链栈的定义:

链队列是一种线性数据结构,采用链表来实现队列的操作。链队列具有队头指针和队尾指针,用于指示队列元素所在的位置。链队列只允许在队尾插入元素,在队头删除元素,符合先进先出(First In First Out,FIFO)的原则。

2、链栈的优缺点:

链队列的优点:

  1. 动态分配空间:链队列使用链表实现,可动态分配和释放空间。因此,不需要预先分配大量存储空间,可以根据实际需求进行空间分配。
  2. 无需移动元素:相比普通队列,链队列在删除元素时无需移动大量元素,只需修改指针即可。这使得链队列在处理大规模数据时具有更高的效率。
  3. 适合处理用户排队等待的情况:链队列适用于处理用户排队等待的情况,例如银行排队、网络请求等。通过链队列,可以快速地插入新用户和删除已处理的用户。

链队列的缺点:

  1. 需要额外的存储空间:为了实现链表结构,链队列需要额外的存储空间来维护指针和节点。这会增加存储空间的消耗。
  2. 插入和删除操作可能引起内存分配和释放:在链队列中插入和删除元素时,可能需要动态分配和释放内存。这会增加操作的时间复杂度,并可能引起内存碎片化问题。
  3. 无法充分利用连续空间的优势:链表结构使得链队列无法像数组一样充分利用连续空间的优势,这会影响空间利用率和访问速度。

二、链队列的基本操作算法(C语言)    

1、宏定义
#define OK 1
#define ERROR 0
#define OVERFLOW -1

#define MAXSIZE 100

typedef int QElemtype;
typedef int Status;
  2、创建结构体
//创建结构体
typedef struct QNode {
    QElemtype data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct {
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;
3、链栈的初始化 
//链队列的初始化
Status InitQueue(LinkQueue &Q) {
    Q.front = Q.rear = (QueuePtr) malloc(sizeof(QNode));
    if (!Q.front) {
        exit(OVERFLOW);
    }
    Q.front->next = NULL;
    return OK;
}
4、链队列的入队 
//链队列的入队 
Status EnQueue(LinkQueue &Q, QElemtype e) {
    QueuePtr p = (QueuePtr) malloc(sizeof(QNode));
    if (!p) {
        exit(OVERFLOW);
    }
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}
5、链队列的出队
//链队列的出队
Status DeQueue(LinkQueue &Q, QElemtype &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    QueuePtr p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) {
        Q.rear = Q.front;
    }
    delete p;
    return OK;

}
6、取链队列的对头元素
//取链列的对头元素 
Status GetQueueHead(LinkQueue &Q, QElemtype &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.front->next->data;
    return OK;

}
7、链队列的销毁
//队列的销毁
Status DestoryQueue(LinkQueue &Q) {
    while (Q.front) {
        Q.rear = Q.front->next;
        delete (Q.front);
        Q.front = Q.rear;
    }
//    printf("销毁成功!");
    return OK;
}
8、链队列的清空
//清空
Status ClearQueue(LinkQueue &Q) {
    Q.rear = Q.front->next;
    while (Q.front->next) {
        Q.rear = Q.rear->next;
        delete (Q.front->next);
        Q.front->next = Q.rear;
    }
    Q.rear = Q.front;
//    printf("清空成功!");
    return OK;
}
9、判断链队列是否为空
//判断是否为空
Status QueueEmpty(LinkQueue &Q) {
    if (Q.front == Q.rear) {
//        printf("队列为空!\n");
        return true;
    } else {
        return false;
    }
//    printf("该队列不为空!");
}
10、求队列长度
//求队列长度
Status QueueLength(LinkQueue Q) {
    int i = 0;
    while (Q.front != Q.rear) {
        i++;
        Q.front = Q.front->next;
    }
//    printf("该队列长度为:%d", i);
    return i;
}
 11、遍历队列元素
//遍历队列
Status QueueTraverse(LinkQueue Q) {
    QNode *p;
    if (Q.front == Q.rear) {
        return ERROR;
    }
    p = Q.front->next;//存储头元素
    printf("从队头依次读出该队列中的元素值为: ");
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
    return OK;
}

三、链队列的基本操作完整代码(C语言)

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

#define OK 1
#define ERROR 0
#define OVERFLOW -1

#define MAXSIZE 100

typedef int QElemtype;
typedef int Status;

//创建结构体
typedef struct QNode {
    QElemtype data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct {
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;

//链队列的初始化
Status InitQueue(LinkQueue &Q) {
    Q.front = Q.rear = (QueuePtr) malloc(sizeof(QNode));
    if (!Q.front) {
        exit(OVERFLOW);
    }
    Q.front->next = NULL;
    return OK;
}

//链队列的入队 
Status EnQueue(LinkQueue &Q, QElemtype e) {
    QueuePtr p = (QueuePtr) malloc(sizeof(QNode));
    if (!p) {
        exit(OVERFLOW);
    }
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

//链队列的出队
Status DeQueue(LinkQueue &Q, QElemtype &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    QueuePtr p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) {
        Q.rear = Q.front;
    }
    delete p;
    return OK;

}

//取链列的对头元素 
Status GetQueueHead(LinkQueue &Q, QElemtype &e) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.front->next->data;
    return OK;

}


//队列的销毁
Status DestoryQueue(LinkQueue &Q) {
    while (Q.front) {
        Q.rear = Q.front->next;
        delete (Q.front);
        Q.front = Q.rear;
    }
//    printf("销毁成功!");
    return OK;
}

//清空
Status ClearQueue(LinkQueue &Q) {
    Q.rear = Q.front->next;
    while (Q.front->next) {
        Q.rear = Q.rear->next;
        delete (Q.front->next);
        Q.front->next = Q.rear;
    }
    Q.rear = Q.front;
//    printf("清空成功!");
    return OK;
}


//判断是否为空
Status QueueEmpty(LinkQueue &Q) {
    if (Q.front == Q.rear) {
//        printf("队列为空!\n");
        return true;
    } else {
        return false;
    }
//    printf("该队列不为空!");
}

//求队列长度
Status QueueLength(LinkQueue Q) {
    int i = 0;
    while (Q.front != Q.rear) {
        i++;
        Q.front = Q.front->next;
    }
//    printf("该队列长度为:%d", i);
    return i;
}


//遍历队列
Status QueueTraverse(LinkQueue Q) {
    QNode *p;
    if (Q.front == Q.rear) {
        return ERROR;
    }
    p = Q.front->next;//存储头元素
    printf("从队头依次读出该队列中的元素值为: ");
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
    return OK;
}


//功能菜单列表
void show_help() {
    printf("******* 功能菜单列表 *******\n");
    printf("1----入队------------------\n");
    printf("2----求链队列长度----------\n");
    printf("3----出队------------------\n");
    printf("4----取队头元素-------------\n");
    printf("5----清空循环队列-----------\n");
    printf("6----销毁循环队列-----------\n");
    printf("7----判断循环队列是否为空-----\n");
    printf("8----批量插入元素------------\n");
    printf("9----显示队列元素------------\n");
    printf("10----退出------------------\n\n");
}


//主函数
int main() {
    LinkQueue LQ;
    Status reIn = InitQueue(LQ);
    if (reIn == OK) {
        printf("链队列初始时成功  \n");
    } else {
        printf("链队列初始时失败 \n");
    }

    while (1) {

        //功能菜单列表
        show_help();

        int flag;
        printf("请输入所需的功能编号:\n");
        scanf("%d", &flag);

        switch (flag) {
            case 1: {//入队
                Status EnQueueindex;
                printf("请输入插入元素(请在英文状态下输入例如:1): \n");
                scanf("%d", &EnQueueindex);
                Status rEnQueue = EnQueue(LQ, EnQueueindex);
                if (rEnQueue == OK) {
                    printf("向链队列入队%d成功!\n", EnQueueindex);
                } else {
                    printf("向链队列入队失败!\n");
                }
            }
                break;
            case 2: {//求链队列的长度
                int length = QueueLength(LQ);
                printf("链队列的长度为:%d。 \n\n", length);
            }
                break;
            case 3: {//出队
                QElemtype DeElem;
                Status DeEn = DeQueue(LQ, DeElem);
                if (DeEn == OK) {
                    printf("从链队列中出队成功,出队的元素为 %d! \n", DeElem);
                } else {
                    printf("从链队列中出队失败!\n");
                }
            }
                break;
            case 4: {//求队头元素
                QElemtype getEl;
                Status reGet = GetQueueHead(LQ, getEl);
                if (reGet == OK) {
                    printf("从链队列中取对头元素成功,队头元素为:%d! \n", getEl);
                } else {
                    printf("从链队列中取对头元素成功 \n");
                }
            }
                break;
            case 5: { //清空
                Status rClearStack = ClearQueue(LQ);
                if (rClearStack == OK) {
                    printf("链队列清空成功!\n");
                } else {
                    printf("链队列清空失败!\n");
                }
            }
                break;
            case 6: {//销毁
                Status rDestroyStack = DestoryQueue(LQ);
                if (rDestroyStack == OK) {
                    printf("链队列销毁成功!\n");
                } else {
                    printf("链队列销毁失败!\n");
                }
            }
                break;
            case 7: {///判空
                Status ClearStatus = QueueEmpty(LQ);
                if (ClearStatus == true) {
                    printf("链队列为空!\n\n");
                } else {
                    printf("链队列不为空!\n\n");
                }
            }
                break;
            case 8: {//批量插入
                int on;
                printf("请输入想要插入的元素个数:\n");
                scanf("%d", &on);
                QElemtype array[on];
                for (int i = 1; i <= on; i++) {
                    printf("向链队列第%d个位置插入元素为:", i);
                    scanf("%d", &array[i]);
                }

                for (int i = 1; i <= on; i++) {
                    Status InsertStatus = EnQueue(LQ, array[i]);
                    if (InsertStatus == OK) {
                        printf("向链队列第%d个位置插入元素%d成功!\n", i, array[i]);
                    } else {
                        printf("向链队列第%d个位置插入元素%d失败!\n", i, array[i]);
                    }
                }
            }
                break;
            case 9: {//输出链表元素
                QueueTraverse(LQ);
//                printf("\n");
            }
                break;
            case 10: {//退出程序
                return 0;
            }
                break;
            default: {
                printf("输入错误,无此功能,请检查输入:\n\n");
            }
        }
    }


    return 1;
}

  四、运行结果

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

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

相关文章

4.列表选择弹窗(CenterListPopup)

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;.NET 7、MAUI 在屏幕中间弹窗的列表选择弹窗。 1.布局 <?xml version"1.0" encoding"utf-8" ?> <toolkit:Popup xmlns"http://schemas.microsoft.com/dotnet/2021/maui"x…

【AIGC】Diffusers:扩散模型的开发手册说明2

前言 扩散器被设计成一个用户友好且灵活的工具箱&#xff0c;用于构建适合您用例的扩散系统。工具箱的核心是模型和调度程序。然而 DiffusionPipeline 为方便起见将这些组件捆绑在一起&#xff0c;但您也可以解包管道并分别使用模型和调度程序来创建新的扩散系统。 解构 Stab…

uniapp组件库Modal 模态框 的使用方法

目录 #平台差异说明 #基本使用 #传入富文本内容 #异步关闭 #点击遮罩关闭 #控制模态框宽度 #自定义样式 #缩放效果 #API #Props #Event #Method #Slots 弹出模态框&#xff0c;常用于消息提示、消息确认、在当前页面内完成特定的交互操作。 #平台差异说明 AppH5微…

gin如何实现热更新

什么是热更新&#xff1f; 一种不需要用户关闭应用或重新启动设备就能进行的软件更新技术。它可以快速地在线修复或升级应用程序的错误或功能&#xff0c;从而减少用户的等待时间并提高用户体验。 如何优雅停止服务&#xff1f; Go 1.8版本之后&#xff0c; http.Server 内置…

CentOS使用

1.使用SSH连接操作虚拟机中的CentOS 使用代理软件(MobaX/Xshell)通过ssh连接vmware中的虚拟机,可以摆脱vmware笨重的软件,直接在代理软件中进行操作. 包括使用云虚拟器,其实也只是在本地通过ssh连接别处的云服务商的硬件而已. 1.1 配置静态IP 为什么要配置静态IP? 想要使用…

构建高可用消息队列系统 01

构建高可用消息队列系统 01 引言1. RabbitMQ简介介绍1.1 什么是RabbitMQ1.2 RabbitMQ的核心特性1.3 RabbitMQ与AMQP 2.安装RabbitMQ3.消息队列实践总结 引言 在当今互联网时代&#xff0c;消息队列系统扮演着至关重要的角色&#xff0c;它们被广泛应用于分布式系统、微服务架构…

Linux编辑器vim(含vim的配置)

文章目录 前言vim的基本概念vim基本操作进入vim模式切换退出vim vim指令vim命令模式指令vim底行模式命令 简单vim配置 前言 本篇文章&#xff0c;小编将介绍Linux编辑器–>vim以及vim的配置。 vim的基本概念 正常/普通/命令模式(Normal mode) 控制屏幕光标的移动&#xf…

年夜饭都吃什么菜?年夜饭菜谱保存到手机便签更便捷

农历除夕&#xff0c;是我国一年中最为重要的传统节日之一&#xff0c;而在这一天&#xff0c;全家团圆共进年夜饭是一种重要的仪式感。然而&#xff0c;随着现代生活的繁忙&#xff0c;很多人都在为年夜饭吃什么菜而发愁。年夜饭是一顿团圆、美好的大餐&#xff0c;选择一些好…

基于非缓冲区文件操作(实现cp的功能)

打开文件 -- open open(const char *pathname, int flags); open(const char *pathname, int flags, mode_t mode); 形参&#xff1a; pathname -- 文件的路径 flags&#xff1a;下面的宏定义必须选择一个 O_RDONLY -- 只读 O_WRONLY -- 只写 O_RDWR --…

selenium执行出现异常,SessionNotCreatedException ChromeDriver only supports

问题现状&#xff1a; 运行程序报错&#xff1a; selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 114 Current browser version is 121.0.6167.85 with binary path /App…

8.6跳跃游戏②(LC45-M)

算法&#xff1a; 与上一题一样&#xff0c;还是看最大覆盖范围 要从覆盖范围出发&#xff0c;不管怎么跳&#xff0c;覆盖范围内一定是可以跳到的&#xff0c;以最小的步数增加覆盖范围&#xff0c;覆盖范围一旦覆盖了终点&#xff0c;得到的就是最少步数&#xff01; 这里…

MyBatis 批量插入数据优化

前言 最近在项目上遇到了批量插入的场景问题&#xff0c;由于每次需要插入超过 10w 的数据量并且字段也蛮多的导致如果使用循环单次插入的方式插入数据插入的效率不高。相信读者们在实际开发中也遇到过这样类似的场景&#xff0c;那么批量插入如何实现呢&#xff1f; 其实我也…

本地部署Tomcat开源服务器并结合内网穿透远程访问

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#xff0…

闲人闲谈PS之五十二——虚拟组装部件超过99的问题

惯例闲话&#xff1a;分享 朱龙春老师的一篇随笔《只是做点ERP&#xff0c;没必要跳楼吧 。 多大的事呢&#xff0c;生命面前&#xff0c;一切都是个P》的感想&#xff0c;故事大致是这样&#xff0c;客户不断提需求&#xff0c;技术出身的愣头青项目经理扛不住项目成本压力&am…

初识Docker(架构、安装Docker)

一、什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者将应用程序及其依赖打包到一个轻量级、可移植的容器中。这些容器可以在不同的计算平台上运行&#xff0c;如Linux和Windows&#xff0c;并且可以实现虚拟化。Docker 的设计目标是提供一种快速且轻量…

C++数据结构——红黑树

一&#xff0c;关于红黑树 红黑树也是一种平衡二叉搜索树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&#xff0c;颜色右两种&#xff0c;红与黑&#xff0c;因此也称为红黑树。 通过对任意一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树可以…

01 质数筛

一、根据概念进行枚举 1、判断质数的枚举算法 根据概念:除了1和它本身以外没有其他约数的数为质数 //输入一个数n&#xff0c;判断n是不是质数 #include<bits/stdc.h> using namespace std;int main(){int n;cin>>n;//根据概念:除了1和它本身以外没有其他约数的…

进程通信与socket编程实践之猜数字小游戏

socket是实现进程通信的一种重要方式&#xff0c;本文将通过socket编程实现服务器进程与客户端进程之间的通信&#xff0c;并在通信之外实现猜数字的小游戏。 1. 设计思路 本文设计的C/S结构的猜数字游戏功能如下&#xff1a;服务器端自动生成一个1-100之间的随机数字&#x…

linux基础学习(7):find命令

1.按照文件名搜索 find 搜索路径 选项 文件名 选项&#xff1a; -name&#xff1a;按文件名搜索 -ineme&#xff1a;不区分文件名大小写搜索 -inum&#xff1a;按inode号搜索 按文件名搜索跟按关键词搜索不一样&#xff0c;只能搜到文件名完整对应的文件 *根据文件名…

加速应用开发:低代码云SaaS和源码交付模式如何选

随着数字化转型的加速&#xff0c;企业对于快速开发和交付高质量应用的需求也越来越迫切。为了满足这一需求&#xff0c;开发者们开始探索采用低代码平台进行软件开发工作&#xff0c;以加速应用开发过程。 目前&#xff0c;市场上的低代码产品众多&#xff0c;但基本可分为简单…