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

news/2024/11/24 11:33:58/

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

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;

}


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

相关文章

Vivado报错:[Runs 36-527] DCP does not exist

Vivado报错:[Runs 36-527] DCP does not exist 问题描述:综合工程时,某个IP文件被标红,出现[Runs 36-527] DCP does not exist...... 的报错 解决办法:如果是在windows系统上用Vivado打开工程,当工程路…

FutureWarning: Passing (type, 1) or ‘1type‘ as a synonym of type is deprecated解决办法

FutureWarning: Passing (type, 1) or ‘1type’ as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / ‘(1,)type’.解决办法 D:\Anaconda\envs\ml\lib\site-packages\tensorflow\python\framework\dtypes.py:523: …

527_linux内核学习_asm.S文件浏览

全部学习汇总: https://github.com/GreyZhang/little_bits_of_linux 前面学习的时候,分析了几段汇编代码之后我基本决定对汇编代码的精读了。这部分,我很可能在未来的工作或者生活学习中用到的很少,而且通用性并不是很好。因此&am…

基于51单片机设计的数字温度计设计

一、项目介绍 数字温度计是一种广泛应用于日常生活和工业领域中的电子测量仪器,用于检测环境温度并将其转换为数字信号进行显示。随着现代科技的发展,数字温度计逐渐取代了传统的水银温度计等方式,具有快速响应、高精度、便携式等优点。 基于51单片机设计的数字温度计具体…

全力支持国产化系统,527轻会议与华为达成鲲鹏生态合作

近日,527轻会议公司正式宣布成功加入鲲鹏展翅伙伴计划,成为该计划的重要战略伙伴。此举标志着527轻会议在国产化兼容性、安全性、可靠性以及产品功能性能等方面得到了权威认证。在视频会议方面的技术实力和服务能力已经得到了业内专家的高度认可。 鲲鹏展…

【Leetcode】527. Word Abbreviation

题目地址: https://leetcode.com/problems/word-abbreviation/description/ 给定若干小写字母的单词,每个单词长度都大于 1 1 1。要求按照下列规则产生所有单词的缩写: 1、每个单词的缩写格式是其前缀 省略的字符个数 最后一个字符&#…