题集-栈和队列的相互转化

 这里,队列的性质是先入先出,但是栈的性质是后入先出。两个队列就可以通过相互捯实现数据的后入先出。

typedef int QDataType;

//这是一个队列结点的结构

typedef struct QueueNode

{

    struct QueueNode* next;

    QDataType data;

}QNode;

//这是一个队列结构

typedef struct Queue

{

    QNode* phead;

    QNode* ptail;

    int size;

}Queue;

//这是通过两个队列搭建的栈结构

typedef struct {

    Queue q1;

    Queue q2;

} MyStack;

//栈的初始化

void QueueInit(Queue* pq)

{

    assert(pq);

    pq->phead = NULL;

    pq->ptail = NULL;

    pq->size = 0;

}

//队列判空

bool QueueEmpty(Queue* pq)

{

    assert(pq);

    return pq->size == 0 ;

}

//栈数据个数

int QueueSize(Queue* pq)

{

    assert(pq);

    return pq->size;

}

//入队

void QueuePush(Queue* pq, QDataType x)

{

    assert(pq);

    QNode* newnode = malloc(sizeof(QNode));

    if (newnode == NULL)

    {

        perror("malloc fail::");

        return;

    }

    newnode->data = x;

    newnode->next = NULL;

    if (pq->ptail == NULL)

    {

        assert(pq->phead == NULL);

        pq->phead = pq->ptail = newnode;

    }

    else

    {

        pq->ptail->next = newnode;

        pq->ptail = newnode;

    }

    pq->size++;

}

//出队列

void QueuePop(Queue* pq)

{

    assert(pq);

    //队列为空

    if(QueueEmpty(pq))

    {

        return NULL;

    }

    //当队列只有一个结点时,ptail会成为野指针,所以要分情况处理

    if (QueueSize(pq)==1)

    {

        free(pq->phead);

        pq->phead = pq->ptail = NULL;

        pq->size = 0;

    }

    else

    {

        QNode* cur = pq->phead;

        pq->phead = pq->phead->next;

        free(cur);

        cur = NULL;

        pq->size--;

    }

}

//获取队首元素

QDataType QueueFront(Queue* pq)

{

    assert(pq);

    if(pq->phead == NULL)

    {

        return NULL;

    }

    return pq->phead->data;

}

//队列的销毁

void QueueDestroy(Queue* pq)

{

    assert(pq);

    if(pq->size == 0) return;

    if(pq->size == 1)

    {

        QueuePop(pq);

    }

    else

    {

    QNode* cur = pq->phead;

    QNode* after = cur->next;

    while (cur)

    {

        free(cur);

        cur = after;

        if (cur)

        {

            after = after->next;

        }

    }

    pq->phead = pq->ptail = NULL;

    pq->size = 0;   

    }

}

//队尾底元素的获取

QDataType QueueBack(Queue* pq)

{

    assert(pq);

    if (QueueEmpty(pq))

    {

        return NULL;

    }

    return pq->ptail->data;

}

//创建栈

MyStack* myStackCreate() {

     MyStack *obj = (MyStack*)malloc(sizeof(MyStack));

     if(obj == NULL)

     {

         perror("malloc fail::");

         return;

     }

        QueueInit(&obj->q1);

        QueueInit(&obj->q2);

    return obj;

}

//压栈

void myStackPush(MyStack* obj, int x) {

      assert(obj);

      if (!QueueEmpty(&obj->q1))

    {

        QueuePush(&obj->q1,x);

    }

    else

    {

        QueuePush(&obj->q2,x);

    }

}

//出栈

int myStackPop(MyStack* obj) {

    assert(obj);

    Queue* pEmptyQ = &obj->q1;

    Queue* pNonEmptyQ = &obj->q2;

    if(!QueueEmpty(&obj->q1))

    {

        pEmptyQ = &obj->q2;

        pNonEmptyQ = &obj->q1;

    }

    while(QueueSize(pNonEmptyQ)>1)

    {

        QueuePush(pEmptyQ,QueueFront(pNonEmptyQ));

        QueuePop(pNonEmptyQ);

    }

    int ret = QueueFront(pNonEmptyQ);

    QueuePop(pNonEmptyQ);

    return ret;

}

//获取栈顶元素

int myStackTop(MyStack* obj) {

    assert(obj);

    if(!QueueEmpty(&obj->q1))

    {

        return QueueBack(&obj->q1);

    }

    else

    {

        return QueueBack(&obj->q2);

    }

}

//栈判空

bool myStackEmpty(MyStack* obj) {

     return (QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2));

}

//栈空间释放

void myStackFree(MyStack* obj) {

     QueueDestroy(&obj->q1);

     QueueDestroy(&obj->q2);

     free(obj);

     obj = NULL;

}

用栈实现队列就不能通过相互捯实现了,因为栈换到另一个栈中时,顺序就是相反的顺序,所以此时压栈顺序和出栈顺序就无法判断。

所以此时,我们将两个栈区分清楚,一个叫做“入”栈,专门用来进数据的,一个叫做“出”栈,专门用来出数据的。

 

 此时要求出数据,若“出”栈内没有数据,则从“入”栈中捯过来,然后再出。若出栈中本来就有数据,则直接出栈即可。

要求入数据时,直接放在“入”栈中即可。

typedef int STDataType;

//栈的结点结构

typedef struct Stack

{

    STDataType* a;

    int top;

    int capacity;

}ST;

//初始化栈

void STInit(ST* pst)

{

    assert(pst);//如果指针为空,无法通过动态申请进行初始化,因为参数为一级指针。

    pst->a = NULL;

    pst->top = 0;

    pst->capacity = 0;

}

//栈判空

bool STEmpty(ST* pst)

{

    assert(pst);

    /*if (pst->top == 0)

        return true;

    else return false;

    */

    return pst->top == 0;

}

//销毁栈

void STDestroy(ST* pst)

{

    assert(pst);

    free(pst->a);

    pst->a = NULL;

    pst->capacity = 0;

    pst->top = 0;

}

//压栈

void STPush(ST* pst,STDataType a)

{

    if (pst->top == pst->capacity)

    {

        int newCapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;

        STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));

        if (tmp == NULL)

        {

            perror("realloc fail::");

            return;

        }

        pst->a = tmp;

        pst->capacity = newCapacity;

    } 

    pst->a[pst->top] = a;

    pst->top += 1;

}

//出栈

void STPop(ST* pst)

{

    assert(pst);

    assert(!STEmpty(pst));

    pst->top--;

}

//获取栈顶元素

STDataType STTop(ST* pst)

{

    assert(pst);

    assert(!STEmpty(pst));

    return pst->a[pst->top - 1];

}

//栈元素个数统计

int STSize(ST* pst)

{

    assert(pst);

    return pst->top;

}

//由两个栈构建的队列结构

typedef struct {

    ST pushst;

    ST popst;

} MyQueue;

//队列的创建

MyQueue* myQueueCreate() {

    MyQueue * obj = (MyQueue*)malloc(sizeof(MyQueue)); 

    if(obj == NULL)

    {

        perror("malloc fail::");

        return;

    }

    STInit(&obj->pushst);

    STInit(&obj->popst); 

    return obj;

}

//入队

void myQueuePush(MyQueue* obj, int x) {

     assert(obj);

     STPush(&obj->pushst,x);

}

//出队

int myQueuePop(MyQueue* obj) {

     assert(obj);

     int ret = 0;

     if(!STEmpty(&obj->popst))

     {

         ret = STTop(&obj->popst);

         STPop(&obj->popst);

     }

     else 

     {

         while(STSize(&obj->pushst))

         {

             STPush(&obj->popst,STTop(&obj->pushst));

             STPop(&obj->pushst);

         }

          ret = STTop(&obj->popst);

         STPop(&obj->popst);

     }

     return ret;

}

//获取队首元素

int myQueuePeek(MyQueue* obj) {

    assert(obj);

    if(!STEmpty(&obj->popst))

     {

         return STTop(&obj->popst);

     }

     else 

     {

         while(STSize(&obj->pushst))

         {

             STPush(&obj->popst,STTop(&obj->pushst));

             STPop(&obj->pushst);

         }

         return STTop(&obj->popst);

     }

}

//队列判空

bool myQueueEmpty(MyQueue* obj) {

    assert(obj);

    return (STEmpty(&obj->pushst)&&(STEmpty(&obj->popst)));

}

//释放队列空间

void myQueueFree(MyQueue* obj) {

     STDestroy(&obj->popst);

     STDestroy(&obj->pushst);

     free(obj);

     obj=NULL;

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常见面试题之MySQL篇

1.MySQL中,如何定位慢查询? 我们当时做压测的时候有的接口非常的慢,接口的响应时间超过了2秒以上,因为我们当时的系统部署了运维的监控系统Skywalking,在展示的报表中可以看到是哪一个接口比较慢,并且可以分析这个接…

ChatGPT在前,华为盘古Chat在后

国产盘古Chat对话方面堪比GPT-3.5 什么是ChatGPT?简单来说,就是一个能够和人类自然对话的人工智能系统。它可以理解你的语言,回答你的问题,甚至给你提供建议和服务。它不仅可以处理文字,还可以处理图片、视频、音频等…

Web3 是什么?为何应该关注?

当我开始我的职业生涯时,“Web2.0”还是一个热门的新事物。 当我开始我的职业生涯时,正值互联网快速发展的时期,人们谈论的是“Web2.0”,这一概念引发了许多关于用户参与、社交媒体和在线合作的讨论。然而,随着时间的推…

DataStructure01|ArrayList和顺序表

ArrayList与顺序表 1.线性表 ​ 线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列… ​ 线性表在逻辑上是线性结构,也就说…

掌握Python的X篇_4_开发工具ipython与vscode的安装使用

本篇将会介绍两个工具的安装及使用来提高Python的编程效率。 ipython:比python更好用的交互式开发环境vscode:本身是文本编辑器,通过安装相关的插件vscode可以作为python集中开发环境使用 掌握Python的X篇_4_开发工具ipython与vscode的安装使…

ChatGPT/GPT-4 或将从根本上改变软件工程

文章目录 一、前言二、主要内容 🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 编程也可能是最容易被 AI 技术取代的工作之一,软件的构建方式将产生根本性的转变。 今年以来,相信大家都听说过 ChatGPT、New Bing 和…

Java try-catch块

Java的try块用于封装可能会抛出异常的代码。它必须在方法内部使用。 如果在try块中的特定语句处发生异常,后续的代码块将不会执行。因此,建议不要在try块中放置不会抛出异常的代码。 Java的try块必须后跟catch块或finally块。 Java try-catch语法 try…

chatgpt赋能python:Python绘制车辆轨迹图

Python绘制车辆轨迹图 在现代交通中,车辆轨迹图是一个广泛应用的技术,它可以被用于道路交通管理,行车安全评估等领域。Python是一种强大的编程语言,它提供了许多绘制数据可视化图表的库。本文将介绍如何使用Python和Matplotlib库…

Git的使用方法

文章目录 Git简介Git用法上传到gitee上 Git简介 简单来说,Git就像一个日志一样,可以帮你记录你对文本文件的修改,但他的功能又强于日志,不仅可以记录,还可以帮你存储那些你对文本文件的修改,当你想要找回之…

ArcGis系列-坐标系转换

Arcgis的工程项目可以添加各种类型的空间资源,比如数据库空间表、shp文件,每张空间表的坐标系可能都会有差异,把他们放到一个工程里时可以统一设置坐标系。 本文将介绍ArcGis三个需要坐标转换的场景: Arcgis Pro设置项目坐标GP分…

论文笔记--GPT-4 Technical Report

论文笔记--GPT-4 Technical Report 1. 报告简介2. 报告概括3 报告重点内容3.1 Predictable Scaling3.2 Capabilities3.3 limitations3.3 Risks & mitigations 4. 报告总结5. 报告传送门6. References 1. 报告简介 标题:GPT-4 Technical Report作者:…

【ABAP】数据类型(四)「类型组TYPE-POOL」

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较…

Mac安装chromedriver

一、chromedriver下载 1、打开chrome浏览器输入:chrome://settings/help 查看当前chrome版本     2、下载对应的chromedriver版本 下载地址:http://chromedriver.storage.googleapis.com/index.html 选择mac系统的chromedriver 直接解压该文件 3、…

SpringBoot使用MockMVC单元测试Controller

前言: 在SpringBoot应用程序中,Controller是接受客户端请求并返回响应数据的核心组件。为了保证Controller的正确性和稳定性,我们可以使用MockMVC框架进行单元测试。MockMVC是Spring框架提供的一个HTTP客户端,用于模拟HTTP请求和响…

华为云“企业快成长大数据与微服务技术创新论坛”成功举办

6月16日,由华为云、msup、厦门火炬大学堂、厦门市行业软件协会联合主办的“企业快成长大数据与微服务技术创新论坛”在厦门成功举办。本次活动汇聚了华为云、珍爱网等知名企业的CTO和技术专家,通过技术案例解析了大数据平台构建、微服务演进等内容&#…

Golang笔记:使用json包处理JSON数据

文章目录 目的Decoding(解析数据)Encoding(创建数据)总结 目的 JSON 是一种非常流行的数据交换格式,是JavaScript中原生支持的一种数据,因为其简单方便,所以也经常用在不同程序、不同语言间数据…

【FPGA入门】第七篇、FPGA实现VGA接口驱动

目录 第一部分、实验结果 1、横的三色彩条效果 2、竖的三色彩条效果 第二部分、VGA驱动基本知识 1、VGA分辨率问题 2、VGA驱动波形 2.1、工业标准的时序波形图 2.2、比上面那张图更容易理解的图 2.3、每个区域对应的时间 2.4、不同分辨率的表格 3、VGA扫描范…

【Vue全家桶高仿小米商城】——(四)项目基础架构

第四章:项目基础架构 此章节全力讲解前端基本项目架构,通过此章节可搭建一个通用性的前端架构,内容涵盖跨域方案、路由封装、错误拦截等。 文章目录 第四章:项目基础架构一、前端跨域解决什么是前端跨域?怎么解决前端…

项目调研丨多区块并行处理公链 Transformers 研究报告

目录 一、项目简介 二、项目愿景 三、特色和优势 (1)速度 (2)安全 (3)可扩展性 (4)高度定制 (5)不可篡改 (6)所有数据公开透…

自然语言处理从入门到应用——动态词向量预训练:双向语言模型

分类目录:《自然语言处理从入门到应用》总目录 对于给定的一段输入文本 w 1 w 2 ⋯ w n w_1w_2\cdots w_n w1​w2​⋯wn​,双向语言模型从前向(从左到右)和后向(从右到左)两个方向同时建立语言模型。这样做…