队列与栈之间的灵魂转换——用栈实现队列、用队列实现栈

如何用栈实现队列?

思路演示

用两个栈实现队列
我们首先创建一个结构体,结构体里面包含两个栈

typedef struct {
    ST one;
    ST two;
} MyQueue;

关于栈的类型(ST)以及创建可参考栈的底层逻辑及实现

在这里插入图片描述

我们对与one这个栈只进行入栈操作(入数据),然后two这个栈负责出栈(出数据)

在这里插入图片描述

当我们需要出栈时候,先检查two栈中是否有数据,如果没有数据,那么对one出栈,入栈到two,直到one为空,如果two栈中有数据,直接出栈(出数据)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

对于(入数据)入栈操作我们可以直接入栈one,但是对于出栈操作我们需要判断two中是否有数据,又是否能交换数据才能出栈,这样才符合队列先进先出特性

代码实现

我们使用的是C语言,C语言没有内置栈,所以需要将已经实现好的栈代码拷贝在一起使用栈代码
常规的增删查改

//定义
typedef struct {
    ST one;
    ST two;
} MyQueue;

//初始化
MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    StackInit(&obj->one);
    StackInit(&obj->two);
    return obj;
}
//入数据
void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->one,x);
}

//出数据
int myQueuePop(MyQueue* obj) {
    if(StackEmpty(&obj->two))
    {
        while(!StackEmpty(&obj->one))
        {
            StackPush(&obj->two,StackTop(&obj->one));
            StackPop(&obj->one);
        }
    }
    int top=StackTop(&obj->two);
    StackPop(&obj->two);
    return top;
}

//返回队列开头数据
int myQueueTop(MyQueue* obj) {
    if(StackEmpty(&obj->two))
    {
        while(!StackEmpty(&obj->one))
        {
            StackPush(&obj->two,StackTop(&obj->one));
            StackPop(&obj->one);
        }
    }
    return StackTop(&obj->two);
}

//判断队列是否为空
bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->one) && StackEmpty(&obj->two);
}

//销毁队列
void myQueueFree(MyQueue* obj) {
    StackDestroy(&obj->one);
    StackDestroy(&obj->two);
    free(obj);
}

如何用队列实现栈?

思路演示

我们用来两个队列实现栈
我们首先创建一个结构体来包含两个队列

typedef struct {
    Queue one;
    Queue two;
} MyStack;

关于队列的类型(Queue)以及创建可参考队列的底层逻辑及实现

在这里插入图片描述
在这里插入图片描述

当我们需要出栈的时候,根据队列(先进先出)的特性,我们进行以下操作

在这里插入图片描述

对one队列(只有一个数据的队列)出数据,这样我们就得到栈顶元素,我们需要进行下一次出栈操作只需要向上述操作再来一次

在这里插入图片描述

不管怎么操作最后都有一个队列为空,用来交换操作再去出栈,而入数据入在不为空的队列里

代码实现

我们使用的是C语言,C语言没有内置队列,所以需要将已经实现好的队列代码拷贝在一起使用队列代码
常规增删查改

//定义
typedef struct {
    Queue one;
    Queue two;
} MyStack;

//初始化
MyStack* myStackCreate() {
    MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&obj->one);
    QueueInit(&obj->two);
    return obj;
}

//入栈
void myStackPush(MyStack* obj, int x) {
    if(!QueueEmpty(&obj->one))
    {
        QueuePush(&obj->one,x);
    }
    else
    {
        QueuePush(&obj->two,x);
    }
}

//出栈
int myStackPop(MyStack* obj) {
    Queue* q=&obj->one;
    Queue* noq=&obj->two;
    if(!QueueEmpty(&obj->two))
    {
        noq=&obj->one;
        q=&obj->two;
    }
    while(QueueSize(q)>1)
    {
        QueuePush(noq,QueueFront(q));
        QueuePop(q);
    }
    int top=QueueFront(q);
    QueuePop(q);
    return top;
}

//得到栈顶元素
int myStackTop(MyStack* obj) {
    if(!QueueEmpty(&obj->one))
        return QueueBack(&obj->one);
    else
        return QueueBack(&obj->two);
}

//判断栈是否为空
bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->one) && QueueEmpty(&obj->two);
}

//栈销毁
void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->one);
    QueueDestroy(&obj->two);
    free(obj);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

侠客cheems

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值