用栈实现队列(OJ题)

一、题目链接:. - 力扣(LeetCode)

二、题解代码

//支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
    STDataType* a;
    int top;		// 栈顶
    int capacity;  // 容量 
}Stack;

// 初始化栈 
void StackInit(Stack* ps);
 //入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);



 //初始化栈 
void StackInit(Stack* ps)
{
    assert(ps);
    ps->a = NULL;
    ps->capacity =0; //将容量初始化为0
    ps->top =0; //栈顶位置初始化为0
}

 //入栈 
void StackPush(Stack* ps, STDataType data)
{
    assert(ps);
    if (ps->capacity == ps->top) //当容量等于栈顶的的标识,说明要进行扩容增加容量
    {
        int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
        STDataType* p = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
        if (p == NULL)
        {
            perror("realloc fail");
            return;
        }
        ps->a = p;
        ps->capacity = newcapacity;
    }
    ps->a[ps->top] = data;
    ps->top++;   //入栈一次,栈顶位置加1

}

 //出栈 
void StackPop(Stack* ps)
{
    assert(ps);
   int ret= StackEmpty(ps);
   if (ret != 0)
   {
       return;
   }
    ps->top--;  //出栈一次,栈顶位置减1
}

 //获取栈顶元素 
STDataType StackTop(Stack* ps)
{
    assert(ps);
    int ret = StackEmpty(ps);
    if (ret != 0)
    {
        return -1;
    }
    int n = ps->top-1; //取栈顶元素,它所在的是第top个,数组下标是top-1
    return ps->a[n];
}

 //获取栈中有效元素个数 
int StackSize(Stack* ps)
{
    assert(ps);
    return ps->top;
}

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps)
{
    assert(ps);
    return ps->top == 0;//top是0,就会返回1.不是0,就会返回0
}

// 销毁栈 
void StackDestroy(Stack* ps)
{
    assert(ps);
    ps->top = ps->capacity = 0;
    free(ps->a);
    ps->a = NULL;
}


typedef struct
{
    Stack A;
    Stack B;
} MyQueue;

//初始化
MyQueue* myQueueCreate();
//入队
void myQueuePush(MyQueue* obj, int x);//入队在有元素的地方
//出队
int myQueuePop(MyQueue* obj);
//取队头元素
int myQueuePeek(MyQueue* obj);
//判断是否为空
bool myQueueEmpty(MyQueue* obj);
//销毁队列
void myQueueFree(MyQueue* obj);


//初始化
MyQueue* myQueueCreate() 
{
    MyQueue* myQueue = (MyQueue*)malloc(sizeof(MyQueue));
    if (myQueue == NULL)
    {
        perror("malloc fail");
        return NULL;
    }

    StackInit(&myQueue->A);//初始化A栈
    StackInit(&myQueue->B);//初始化B栈

    return myQueue;
 }

    //入队
    void myQueuePush(MyQueue * obj, int x)//入队在有元素的地方
    {
        if (!StackEmpty(&obj->A))//如果A栈不为空
        {
            StackPush(&obj->A, x);//元素入A栈
        }
        else   //如果A栈为空,元素入B栈
        {
            StackPush(&obj->B, x);//元素入B栈
        }
    }


    //出队
    int myQueuePop(MyQueue * obj) 
    {
        //假设法
        Stack  *Empty = &obj->A;  //先假设A为空,B为非空
        Stack  *NoEmpty =&obj->B;

        if (!StackEmpty(&obj->A))//如果A栈不为空,交换Empty 和NoEmpty
        {
              Empty = &obj->B;  //先假设A为空,B为非空
             NoEmpty =& obj->A;
        }

        while (!StackEmpty(NoEmpty))//将非空的栈(NoEmpty)里的元素依次出栈,并入栈到空栈(Empty)里面
        {
            STDataType temp = StackTop(NoEmpty);//取栈顶元素
            StackPop(NoEmpty);//栈顶元素出栈
            StackPush(Empty, temp);//将出栈的元素,入栈到空栈中
        }


        //将(NoEmpty)栈中的元素依次转到(Empty)栈中,这时的状态变了((Empty)栈有元素,(NoEmpty)栈无元素)
        
        STDataType fist = StackTop(Empty);//取这时(Empty)栈(现在有元素了)的栈顶元素,
        StackPop(Empty);//栈顶元素出栈,也就是队列的队头元素

        //将(Empty)栈中的元素依次还给(NoEmpty)栈,回到之前的状态((Empty)栈无元素,(NoEmpty)栈有元素)

        while (!StackEmpty(Empty))//将非空的栈里的元素依次出栈,并入栈到空栈里面
        {
            STDataType temp = StackTop(Empty);//取栈顶元素
            StackPop(Empty);//栈顶元素出栈
            StackPush(NoEmpty, temp);//将出栈的元素,入栈到(NoEmpty)中
        }

        return fist;//将队列的队头元素返回
        
    }

    //取队头元素
    int myQueuePeek(MyQueue * obj) 
    {
        //假设法
        Stack NoEmpty;//先假设B为非空,

        if (!StackEmpty(&obj->A))//如果A栈不为空,交换Empty 和NoEmpty
        {
            NoEmpty = obj->A;  //先假设A为空,B为非空
        }
        else
            NoEmpty = obj->B;

        while (StackSize(&NoEmpty) > 1)//将非空的栈(NoEmpty)里的元素依次出栈,并入栈到空栈(Empty)里面,
            //留下最后一个
        {
            STDataType temp = StackTop(&NoEmpty);//取栈顶元素
            StackPop(&NoEmpty);//栈顶元素出栈
        }
        STDataType fist = StackTop(&NoEmpty);//取这时(NoEmpty)栈
        StackPop(&NoEmpty);//栈顶元素出栈
        return fist;//将队列的队头元素返回
    }

    //判断是否为空
    bool myQueueEmpty(MyQueue * obj)
    {
        if (obj->A.top == 0 && obj->B.top == 0)//两个栈都是空,说明队列为空了
            return true;
        else
            return false;
    }

    //销毁队列
    void myQueueFree(MyQueue * obj)
    {
        StackDestroy(&obj->A);//销毁A栈
        StackDestroy(&obj->B);//销毁B栈
        free(obj);//释放申请的myQueue
    }

三、思路方法

1.有两个队列,每次 元素进栈的时候   插入数据在已经有数据的队列之中
 假设有数据的是A队列,没有元素的是B队列

2.元素出栈时,就是将有将存储了数据的队列(A队列)里面的元素依次出队列,
 并依次入队列到另一个开始没存储数据的队列(B队列)中,
 但是要留下最后一个元素在A队列,这时候就将A队列的那个最后的数据出队返回,这就是我们要的栈顶元素

这时A队列为空,B队列有数据。

循环执行以上的操作
 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值