数据结构——队的基本操作

news/2024/10/22 11:02:38/

一、顺序队

队的用法:先进先出

跟平时我们遇到的大多情况一样,队的主要思想就是先进先出,比如我去食堂打饭,我先排那么就是我先打到饭咯

顺序队:其实说白了就是一块空间用两个指针去指向,为了实现先进先出的功能

需要注意:这里的两个指针指向,每次入队,队尾指针++,每次出队,队头指针也是++

而且入队要考虑从无到有的情况,出队要考虑从有到无的情况

1、定义

队的定义

//数据类型的定义

typedef int ElemType;

//顺序栈的定义

typedef struct Circlequeue

{

    ElemType data[MAX_LEN];//直接定义一个数组

    int front;//队首的下标

    int rear;//队尾下标

    int num;//队中元素的个数

}CQ;

需要注意的是这里的front rear num都是整型,不是指针 ,后面画图的时候,将front和rear用一条直线连向空间,不是指向哦,不是指针,只是为了表示下标的位置

2、初始化

首先创建一个空队列,使它存在

/*

    函数名:InitQueue

    参数列表:无

    返回值:创建空队的地址

*/

CQ* InitQueue()

{

    //创建一个队列,并且初始化

    CQ* cq=(CQ*)malloc(sizeof(CQ));

    cq->front=-1;

    cq->rear=-1;

    cq->num=0;

    //返回队列的地址

    return cq;

}

3、入队 

将一个数值入队,例如:EnQueue(cq,1)

/*

    函数名:EnQueue

    参数列表:需要入队的队的地址@cq 要入队的元素d

    返回值:成功入队返回1,失败返回0

*/

int EnQueue(CQ* cq,ElemType d)

{

    //如果不能入队的情况

    if(cq==NULL||cq->num==MAX_LEN)

    {

        return 0;

    }

    //入队

    if(cq->num==0)

    {

        cq->front=(cq->front+1)%MAX_LEN;

        cq->rear=(cq->rear+1)%MAX_LEN;

        //只能从队尾入队

        cq->data[cq->rear]=d;

    }

    else

    {

        cq->rear=(cq->rear+1)%MAX_LEN;

        ca->data[ca->rear]=d;

    }

    cq->num++;

    return 1;

}

4、出队 

将一个数值出队到某一特定的空间中去(d),例如:DeQueue(cq,&d)

/*

    函数名:DeQueue

    参数列表:要出队的队列@cq,出队的数据存放地址

    返回值:成功返回1,失败返回0

*/

CQ* DeQueue(CQ* cq,ElemType* d)

{

    if(cq==NULL||cq->num==0)

    {

        return 0;

    }

    *d=cq->data[ca->front];

    cq->num--;

    if(cq->num==0)

    {

        //假如出队出完了:队头和队尾都要重新改变

        cq->front=(cq->front+1)%MAX_LEN;

        cq->rear=(cq->rear+1)%MAX_LEN;

    }

    {

        //只能从队头出队

        cq->front=(cq->front+1)%MAX_LEN;

    }

    return 1;

}

5、求队列长度

/*

    函数名:Queuelength

    参数列表:传进去一个队列的地址@cq

    返回值:返回队列的长度

*/

int Queuelength(CQ* cq)

{

    if(cq==NULL||cq->num==0)

    {

        return 0;

    }

    return cq->num;

}

6、获取队头数据

/*

    函数名:Gethead

    参数列表:传进去一个队的地址@cq,还有一个存放队头数据的空间地址@&d

    返回值:成功获取返回1,失败返回0

*/

ElemType Gethead(CQ* cq,ElemType* d)

{

    if(cq==NULL||cq->num==0)

    {

        return 0;

    }

    *d=cq->data[ca->front];

    return 1;

}

7、判断一个队列是否为空

/*

    函数名:Ifempty

    参数列表:传进去一个队的地址@cq

    返回值:空返回1,非空返回0

*/

int Ifempty(CQ* cq)

{

    if(cq==NULL||cq->num==0)

    {

        return 1;

    }

    return 0;

}

8、清空一个队

/*

    函数名:Clearqueue

    参数列表:传进去一个队列的地址@cq

    返回值:无

*/

void Cleadqueue(CQ* cq)

{

    if(cq)

    {

        cq->front=-1;

        cq->rear=-1;

        cq->num=0;

    }

}

9、销毁一个顺序队 

先清空,使其初始化,再释放申请的队的空间

/*

    函数名:Destroyqueue

    参数列表:传进去一个队列的地址@cq

    返回值:无

*/

void Destroyqueue(CQ* cq)

{

    //定义的时候可以互相调用

    Cleadqueue(cq);

    free(cq);

}

10、打印一个顺序队

/*

    函数名:Print_cqueue

    参数列表:传进去一个队@cq

    返回值:成功打印返回1 失败返回0

*/

int Print_cqueue(CQ* cq)

{

    if(cq==NULL||cq->num==0)

    {

        return 0;

    }

    ElemType d;

    printf("现在顺序队开始出队,出队方式是从链头一一出:");

    while(!Ifcqempty(cq))

    {

        //每出队一次,打印一次

        Decqueue(cq,&d);

        printf("%d ",d);

    }

    printf("\n");

    return 0;

}

 

11、帮助理解图 

二、链式队

每输入一个数据,开辟一块空间并入队,灵活存取

每出队一个数据,先保存要出队的数据,再将曾经为了保存这个数据开辟的空间释放掉,而且不能影响现有队列的结构和操作

1、链式队的定义

队中每个数据的功能先设置单一点,只能指向下一个数据,既不能双向,也不能循环

队中存放数据的数据结点的定义

typedef struct node

{

    ElemType data;

    struct node* next;

}

“头结点”——队的定义 

typedef struct Linkqueue

{

    Node* front;

    Node* rear;

    int num;

}LQ;

2、链式栈的初始化

 /*

    函数名:Initqueue

    参数列表:无

    返回值:返回创建好的链式队的地址

*/

LQ* Initqueue()

{

    LQ* lq=(LQ*)malloc(sizeof(LQ));

    lq->front=NULL;

    lq->rear=NULL;

    lq->num=0;

    return lq;

}

3、入队 

/*

    函数名:Enqueue

    参数列表:要入队的队列lq数值d

    返回值:成功入队返回1,失败返回0

*/

int Enqueue(LQ* lq,ElemType d)

{

    Node* pnew=(Node*)malloc(sizeof(Node));

    pnew->data=d;

    pnew->next=NULL;

    if(lq==NULL)

    {

        return 0;

    }

    if(lq->num==0)

    {

        lq->front=pnew;

        lq->rear=pnew;

    }

    else

    {

        lq->rear->next=pnew;

        lq->rear=pnew;

    }

    lq->num++;

}

4、出队

/*

    函数名:Dequeue

    参数列表:出队的队列和数据lq存放的空间d

    返回值:成功出队返回1 失败返回0

*/

int Dequeue(LQ* lq,ElemType* d)

{

    if(lq==NULL||lq->num==0)

    {

        return 0;

    }

    //遍历删除指针

    Node* px=lq->front;

    *d=lq->front->data;

    if(px->next==NULL)

    {

        //只有一个结点的时候

        lq->front=NULL;

        lq->next=NULL;

    }

    else

    {

        lq->front=lq->front->next;

        px->next=NULL;

    }

    free(px;)

    l->num--;

    return 1;

}

 5、求队列长度

/*

    函数名:Queuelength

    参数列表:指向队列的指针

    返回值:队列长度

*/

int Queuelength(LQ* lq)

{

    if(lq==NULL)

    {

        return 0;

    }

    return lq->num;

}

6、获取队头元素

/*

    函数名:Gethead

    参数列表:队列的地址指针lq和队首元素存放的空间d

    返回值:成功返回1  失败返回0

*/

ElemType Gethead(LQ* lq,ElemType* d)

{

    if(lq==NULL||lq->num==0)

    {

        return 0;

    }

    *d=lq->front->data;

    return 1;

}

7、判断队列是否为空

/*

    函数名:Ifempty

    参数列表:传进去一个指向队列的地址lq

    返回值:空返回1  非空返回0

*/

int Ifempty(LQ* lq)

{

    if(lq==NULL||lq->num==0)

    {

        return 1;

    }

    return 0;

}

 8、清空队列

/*

    函数名:Clearqueue

    参数列表:传进去指向队列的地址lq

    返回值:无

*/

void Cleadqueue(LQ* lq)

{

    if(lq==NULL)

    {

        return ;

    }

    //遍历清除指针

    Node* px=lq->front;

    while(px)

    {

        lq->front=lq->front->next;

        px->next=NULL;

        free(px);

        lq->num--;

        px=lq->front;

    }

    lq->rear=NULL;

    lq->num=0;

    return ;

}

9、销毁队列

/*

    函数名:Destroyqueue

    参数列表:传进去指向队列的地址lq

    返回值:无

*/

void Destroyqueue(LQ* lq)

{

    if(lq==NULL)

    {

        return ;

    }

    //遍历清除指针

    Node* px=lq->front;

    while(px)

    {

        lq->front=lq->front->next;

        px->next=NULL;

        free(px);

        lq->num--;

        px=lq->front;

    }

    lq->rear=NULL;

    lq->num=0;

    free(lq);

}

10、打印一个链式队

/*

    函数名:Print_lqueue

    参数列表:传进去一个队@lq

    返回值:成功打印返回1 失败返回0

*/

int Print_lqueue(LQ* lq)

{

    if(lq==NULL||lq->num==0)

    {

        return 0;

    }

    ElemType d;

    printf("现在链式栈开始出队,出队方式是从链头一一出:");

    while(!Iflqempty(lq))

    {

        Delqueue(lq,&d);

        printf("%d ",d);

    }

    printf("\n");

    return 0;

}

 11、帮助理解图

三、主函数代码实现及运行结果演示 

#include <stdio.h>

#include <stdlib.h>

#include "Treelian.h"

int main()

{

    //顺序队实现:我设置了队里面最大存放个数是10

    printf("现在开始验证顺序队,开辟int数据空间个数是10!\n");

    CQ* cq=Initcqueue();

    printf("从队尾入队:现在将2、4、6、8、10入队!\n");

    //入队方式1

    Encqueue(cq,2);

    Encqueue(cq,4);

    Encqueue(cq,6);

    Encqueue(cq,8);

    Encqueue(cq,10);

    //入队方式2

    // int d1;

    // while(1)

    // {

    //     scanf("%d",&d1);

    //     if(d1==0)

    //     {

    //         break;

    //     }

    //     Encqueue(cq,d1);

    // }

    Print_cqueue(cq);

    printf("-------------------------------------------------------------------------------\n");

    //链式队实现:输入一个数开辟一块空间 出队一个数释放一块空间

    printf("现在开始验证链式队\n");

    LQ* lq=Initlqueue();

    int d2;

    printf("请输入你要入队的数据(这里数据个数不做限制),规定直到输入0表示结束:\n");

    while(1)

    {

        scanf("%d",&d2);

        if(d2==0)

        {

            break;

        }

        Enlqueue(lq,d2);

    }

    //出队

    Print_lqueue(lq);

    return 0;

}

 这个是gcc编译器调试结果示意图


以上是我对数据结构中栈内容的学习记录, 其中有说法不准确的地方欢迎各位朋友指出!


http://www.ppmy.cn/news/1517430.html

相关文章

大数据测试怎么做,数据应用测试、数据平台测试、数据仓库测试

本期内容由中通科技高级质量工程师龙渊在公益讲座中分享&#xff0c;他从大数据测试整体介绍、数据应用测试、数据平台测试以及数据仓库测试等方面&#xff0c;与大家共同探讨了大数据测试的方法实施与落地。 以下是讲座正文&#xff1a; 今天我们分享的内容主要从大数据简介…

【数据结构入门】排序算法之插入排序与选择排序

目录 前言 一、排序的概念及运用 1.排序的概念 2.排序的运用 3.常见排序算法 二、插入排序与选择排序 2.1插入排序 2.1.1直接插入排序 1&#xff09;基本思想 2&#xff09;具体步骤 3&#xff09;算法特性 4&#xff09;算法实现 2.1.2希尔排序 1) 基本思想 2&…

mp总结 mybatisPlus

一、准备 1.引入依赖&#xff08;引入后可以不再引mybatis依赖&#xff09; <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version> </dependency> 2.…

大数据学习路线基础指南‌

随着信息技术的迅猛发展&#xff0c;‌大数据已成为当今社会的热门话题。‌无论是企业决策、‌市场分析还是科学研究&#xff0c;‌大数据都扮演着举足轻重的角色。‌对于想要投身这一领域的学习者来说&#xff0c;‌制定一份清晰、‌系统的大数据学习路线是至关重要的。‌提供…

Day50 | 108.冗余连接 109.冗余连接II

108.冗余连接 108. 冗余连接 题目 题目描述 树可以看成是一个图&#xff08;拥有 n 个节点和 n - 1 条边的连通无环无向图&#xff09;。 现给定一个拥有 n 个节点&#xff08;节点标号是从 1 到 n&#xff09;和 n 条边的连通无向图&#xff0c;请找出一条可以删除的边&…

主流短视频评论采集python爬虫(含一二级评论内容)

声明 仅用于学习交流&#xff0c;不用于其他用途 正文 随着主流短视频评论采集更新需要登录&#xff0c;由于不懈的努力&#xff0c;攻破这一难点&#xff0c;不需要登录采集作品所有评论信息 话不多说上代码看效果&#xff1a; 输入作品id: 这样就拿到评论信息了&#xff…

解决 `java.sql.SQLException` 的正确方法

在开发过程中&#xff0c;java.sql.SQLException 是一个常见但令人头疼的问题。这篇博客将带你一步步分析该异常的产生原因&#xff0c;并提供切实有效的解决方案。 1. 问题分析 java.sql.SQLException 是 JDBC 中的通用异常&#xff0c;通常在数据库操作失败时抛出。它可以由…

图表检测检测系统源码分享 # [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

图表检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …