栈和队列的相互实现

使用两个栈实现一个队列

  • 要实现Push接口其实不难,因为我们只需要向一个栈里面Push数据即可,我们暂且将这个栈定义为栈一,另一个栈设定为栈二
  • 要实现Pop接口的话,其实只要先判断栈二是否为空栈,如果栈二不为空那么直接Pop出一个元素即可,如果栈二不为空,那么需要先将栈一中的元素全部转移到栈二中,然后栈二就有元素了,直接Pop出一个即可!
#include "Topic.h"
void QueueByTwoStackInit(QueueByTwoStack* qts)
{
    assert(qts);
    StackInit(&(qts->s1));
    StackInit(&(qts->s2));
}

void QueueByTwoStackDestory(QueueByTwoStack* qts)
{
    assert(qts);
    StackDestory(&(qts->s1));
    StackDestory(&(qts->s2));
}

//永远向栈一Push元素
void QueueByTwoStackPush(QueueByTwoStack* qts, DataType x)
{
    assert(qts);
    StackPush(&(qts->s1),x);
}

void QueueByTwoStackPop(QueueByTwoStack* qts)
{
    assert(qts);
    //如果栈二为空需要先将栈一中的元素全部转移到栈二中
    if (StackEmpty(&(qts->s2)) == 0) 
    {
        while (StackEmpty(&(qts->s1)))
        {
            StackPush(&(qts->s2), StackTop(&(qts->s1)));
            StackPop(&(qts->s1));
        }
    }
    StackPop(&(qts->s2));
}

DataType QueueByTwoStackFront(QueueByTwoStack* qts)
{
    assert(qts);
    if (StackEmpty(&(qts->s2)) == 0)
    {
        while (StackEmpty(&(qts->s1)))
        {
            StackPush(&(qts->s2), StackTop(&(qts->s1)));
            StackPop(&(qts->s1));
        }
    }
    return StackTop(&(qts->s2));
}

int QueueByTwoStackSize(QueueByTwoStack* qts)
{
    assert(qts);
    return StackSize(&(qts->s1)) + StackSize(&(qts->s2));
}

int QueueByTwoStackEmpty(QueueByTwoStack* qts)
{
    assert(qts);
    return StackEmpty(&(qts->s1)) | StackEmpty(&(qts->s2));
}

void TestQueueByTwoStack()
{
    QueueByTwoStack qs;
    QueueByTwoStackInit(&qs);
    QueueByTwoStackPush(&qs, 11);
    QueueByTwoStackPush(&qs, 22);
    QueueByTwoStackPush(&qs, 33);
    QueueByTwoStackPush(&qs, 44);
    QueueByTwoStackPop(&qs);
    QueueByTwoStackPop(&qs);
    QueueByTwoStackPush(&qs, 55);

    QueueByTwoStackDestory(&qs);
}

这里写图片描述

使用两个队列实现一个栈

接下来是两个队列实现一个栈,首先先大致说一下怎么实现?
这里写图片描述
如图所示,两个队列总有一个是空队列,一个是非空队列,要入栈的话,必须要入非空队列,出栈的话,必须让非空队列将元素转移到空队列里面,直到非空队列剩余一个元素,然后将剩余的这一个元素出队列,即可完成“出栈”

#include "motive.h"

//初始化
void StackByTwoQueueInit(StackByTwoQueue* stq)
{
    assert(stq);
    QueueInit(&(stq->q1));
    QueueInit(&(stq->q2));
}

//销毁
void StackByTwoQueueDestory(StackByTwoQueue* stq)
{
    assert(stq);
    QueueDestory(&(stq->q1));
    QueueDestory(&(stq->q2));
}

//分配空队列与非空队列
static EmptyCmp(Queue** em, Queue** noem, StackByTwoQueue** pstq)
{
    assert(stq);
    QueueEmpty(&(*pstq)->q1) == 1 ? ((*noem = &(*pstq)->q1), *em = &((*pstq)->q2)) : ((*noem = &(*pstq)->q2), *em = &((*pstq)->q1));
}
//获取顶部数据
DataType StackByTwoQueueTop(StackByTwoQueue* stq)
{
    assert(stq);
    Queue *empty;
    Queue *noempty;
    DataType ret;
    //通过三元运算符确定空队列与非空队列
    EmptyCmp(&empty, &noempty, &stq);

    //将非空队列的元素转移到非空队列,保留一个
    while (QueueSize(noempty) > 1)
    {
        QueuePush(empty, QueueFront(noempty));
        QueuePop(noempty);
    }
    //获取保留结果数据
    ret = QueueFront(noempty);
    //将剩下的一个数据也转移
    QueuePop(noempty);
    QueuePush(empty, ret);
    return ret;
}

//判断模拟栈是否为空,为空返回0,不为空返回1
int StackByTwoQueueEmpty(const StackByTwoQueue* stq)
{
    assert(stq);
    //只要有一个队列不为空那么模拟栈就不为空
    return QueueEmpty(&(stq->q1)) | QueueEmpty(&(stq->q2));
}

//模拟栈中存入的元素个数
int StackByTwoQueueSize(const StackByTwoQueue* stq)
{
    assert(stq);
    return QueueSize(&(stq->q1)) + QueueSize(&(stq->q2));
}

//Push数据
void StackByTwoQueuePush(StackByTwoQueue* stq, DataType x)
{
    Queue *empty;
    Queue *noempty;
    assert(stq);
    EmptyCmp(&empty, &noempty, &stq);

    //永远向不为空的队列插入数据
    QueuePush(noempty,x);
}

//Pop数据
void StackByTwoQueuePop(StackByTwoQueue* stq)
{
    Queue *empty;
    Queue *noempty;
    assert(stq);
    EmptyCmp(&empty, &noempty, &stq);

    //与StackByTwoQueueTop()一样的过程,只是最后余下的元素直接出队列
    while (QueueSize(noempty) > 1)
    {
        QueuePush(empty, QueueFront(noempty));
        QueuePop(noempty);
    }
    printf("Pop:%d\n", noempty->_front->_data);
    QueuePop(noempty);
}

//测试函数
void TestStackByTwoQueue()
{
    StackByTwoQueue sq;
    StackByTwoQueueInit(&sq);
    StackByTwoQueuePush(&sq, 11);
    StackByTwoQueuePush(&sq, 22);
    StackByTwoQueuePush(&sq, 33);
    StackByTwoQueuePush(&sq, 44);
    StackByTwoQueuePop(&sq);
    StackByTwoQueuePop(&sq);
    StackByTwoQueuePush(&sq, 55);
    StackByTwoQueuePop(&sq);
    StackByTwoQueuePop(&sq);
    StackByTwoQueuePop(&sq);
    StackByTwoQueueDestory(&sq);
}

猜你喜欢

转载自blog.csdn.net/m0_38032942/article/details/81777091