当前位置: 首页 > news >正文

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

一、顺序队

队的用法:先进先出

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

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

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

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

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编译器调试结果示意图


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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • MongonDB-索引
  • 集成电路学习:什么是ARM先进精简指令集计算机
  • 旗帜分田(华为od机考题)
  • 探索生活服务 API 接口的神奇之处
  • 国风高铁站可视化:传统文化与现代科技的融合
  • Ascend C算子开发(入门)—— 什么是算子?
  • 海外新闻稿发布对区块链项目具有深远的影响
  • .NET WPF 抖动动画
  • 面试官让简述一下elasticsearch
  • 使用 Nginx 部署 Vue.js 项目详解
  • 恺英网络:有业绩,无“游戏”
  • C语言典型例题56
  • 【SQL基础】【leetcode】SQL50题
  • Java算法之插入排序(Insertion Sort)
  • 基于STM32的RFID高速收费系统(论文+源码+实物)
  • ----------
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • CSS魔法堂:Absolute Positioning就这个样
  • ESLint简单操作
  • happypack两次报错的问题
  • Java 最常见的 200+ 面试题:面试必备
  • java取消线程实例
  • laravel with 查询列表限制条数
  • laravel 用artisan创建自己的模板
  • Object.assign方法不能实现深复制
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • Service Worker
  • Vultr 教程目录
  • 前端之React实战:创建跨平台的项目架构
  • 区块链技术特点之去中心化特性
  • 深度学习在携程攻略社区的应用
  • 学习HTTP相关知识笔记
  • 你对linux中grep命令知道多少?
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • (2020)Java后端开发----(面试题和笔试题)
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (二)hibernate配置管理
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置
  • (原)本想说脏话,奈何已放下
  • (转)用.Net的File控件上传文件的解决方案
  • .axf 转化 .bin文件 的方法
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Core 中插件式开发实现
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET开源纪元:穿越封闭的迷雾,拥抱开放的星辰
  • @vueup/vue-quill使用quill-better-table报moduleClass is not a constructor
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [ NOI 2001 ] 食物链
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • [240607] Jina AI 发布多模态嵌入模型 | PHP 曝新漏洞 | TypeScript 5.5 RC 发布公告
  • [acwing周赛复盘] 第 94 场周赛20230311