LeetCode每日精进:232.用栈实现队列

题目链接:232.用栈实现队列

题目描述:

        请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

    提示:

    • 1 <= x <= 9
    • 最多调用 100 次 pushpoppeek 和 empty
    • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

    思路

            定义两个栈,一个用来入队列,一个用来出队列

     1.队列的结构

    typedef struct {
        Stack pushST;
        Stack popST;    
    } MyQueue;
    

            定义pushST来实现入队列,popST来实现出队列。

    2.队列的创建

            申请我们定义的队列的空间,并将pushST和popST初始化,返回指向队列的指针。

    MyQueue* myQueueCreate() {
        MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));
        StackInit(&pq->pushST);
        StackInit(&pq->popST);
        return pq;
    }

    3.入队列

    void myQueuePush(MyQueue* obj, int x)

            将数据直接插入pushST即可。

    void myQueuePush(MyQueue* obj, int x) {
        StackPush(&obj->pushST,x);
    }

    4.出队列

            当popST中没有数据时:

     

            如图所示,现在队列中有4个数据,现在要将数据1出队列,对应pushST里的位于栈底的1 ,由于我们需要将1移至栈顶才能使1出栈,所以这里我们将pushST中的所有元素全部循环取栈顶,出栈顶,插入到pushST中。

            再将popST出栈即可。

    代码实现:

        if (StackEmpty(&obj->popST))
        {
            while(!StackEmpty(&obj->pushST))
            {
                StackPush(&obj->popST,StackTop(&obj->pushST));
                StackPop(&obj->pushST);
            }
        }

            当popST中有数据时:

            直接保存popST栈顶,出栈。

    代码实现:

        int top = StackTop(&obj->popST);
        StackPop(&obj->popST);

    完整代码:

    int myQueuePop(MyQueue* obj) {
        if (StackEmpty(&obj->popST))
        {
            while(!StackEmpty(&obj->pushST))
            {
                StackPush(&obj->popST,StackTop(&obj->pushST));
                StackPop(&obj->pushST);
            }
        }
        int top = StackTop(&obj->popST);
        StackPop(&obj->popST);
        return top;    
    }

    5.返回队列开头元素

    int myQueuePeek(MyQueue* obj)

                     

            若popST为空,将pushST中的元素,取栈顶,出栈顶,插入到popST中,再用top记录popST的栈顶并返回。

     

            若popST不为空,直接返回popST栈顶即可。

    代码实现:

    int myQueuePeek(MyQueue* obj) {
        if (StackEmpty(&obj->popST))
        {
            while(!StackEmpty(&obj->pushST))
            {
                StackPush(&obj->popST,StackTop(&obj->pushST));
                StackPop(&obj->pushST);
            }
        } 
        int top = StackTop(&obj->popST);
        return top;           
    }

    6.判空

    bool myQueueEmpty(MyQueue* obj)

            

            若popST与pushST中任意一个不为空,则队列不为空,返回false。

            若popST与pushST都为空,则队列为空,返回true。

    代码实现:

    bool myQueueEmpty(MyQueue* obj) {
        return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);    
    }

    7.销毁

    void myQueueFree(MyQueue* obj)

            在将popST和pushST销毁后,由于obj是接收了myQueueCreate()的返回值,函数中申请了MyQueue类型的空间,所以还得将obj所指向的空间释放并置空。

    代码实现:

    void myQueueFree(MyQueue* obj) {
        StackDestroy(&obj->pushST);
        StackDestroy(&obj->popST);
        free(obj);
        obj = NULL;    
    }
    

    代码总览:

    typedef int STDataType;
    typedef struct Stack
    {
    	STDataType* _a;
    	int _top;		// 栈顶
    	int _capacity;  // 容量 
    }Stack;
    
    // 初始化栈 
    void StackInit(Stack* ps)
    {
    	ps->_a = NULL;
    	ps->_top = ps->_capacity = 0;
    }
    
    // 入栈 
    void StackPush(Stack* ps, STDataType data)
    {
    	assert(ps);
    	if (ps->_top == ps->_capacity)
    	{
    		int newcapacity = ps->_capacity == 0 ? 4 : 2 * ps->_capacity;
    		STDataType* tmp = (STDataType*)realloc(ps->_a, newcapacity * sizeof(STDataType));
    		if (tmp == NULL)
    		{
    			perror("realloc");
    			exit(1);
    		}
    		ps->_a = tmp;
    		ps->_capacity = newcapacity;
    	}
    	ps->_a[ps->_top++] = data;
    }
    
    // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
    int StackEmpty(Stack* ps)
    {
    	assert(ps);
    	return ps->_top == 0;
    }
    
    // 出栈 
    void StackPop(Stack* ps) 
    {
    	assert(!StackEmpty(ps));
    	--ps->_top;
    }
    
    // 获取栈顶元素 
    STDataType StackTop(Stack* ps)
    {
    	assert(!StackEmpty(ps));
    	return ps->_a[ps->_top - 1];
    }
    
    // 获取栈中有效元素个数 
    int StackSize(Stack* ps)
    {
    	assert(ps);
    	return ps->_top;
    }
    
    // 销毁栈 
    void StackDestroy(Stack* ps)
    {
    	if (ps->_a)
    		ps->_a = NULL;
    	ps->_top = ps->_capacity = 0;
    }
    
    
    typedef struct {
        Stack pushST;
        Stack popST;    
    } MyQueue;
    
    
    MyQueue* myQueueCreate() {
        MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));
        StackInit(&pq->pushST);
        StackInit(&pq->popST);
        return pq;
    }
    
    void myQueuePush(MyQueue* obj, int x) {
        StackPush(&obj->pushST,x);
    }
    
    int myQueuePop(MyQueue* obj) {
        if (StackEmpty(&obj->popST))
        {
            while(!StackEmpty(&obj->pushST))
            {
                StackPush(&obj->popST,StackTop(&obj->pushST));
                StackPop(&obj->pushST);
            }
        }
        int top = StackTop(&obj->popST);
        StackPop(&obj->popST);
        return top;    
    }
    
    int myQueuePeek(MyQueue* obj) {
        if (StackEmpty(&obj->popST))
        {
            while(!StackEmpty(&obj->pushST))
            {
                StackPush(&obj->popST,StackTop(&obj->pushST));
                StackPop(&obj->pushST);
            }
        } 
        int top = StackTop(&obj->popST);
        return top;           
    }
    
    bool myQueueEmpty(MyQueue* obj) {
        return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);    
    }
    
    void myQueueFree(MyQueue* obj) {
        StackDestroy(&obj->pushST);
        StackDestroy(&obj->popST);
        free(obj);
        obj = NULL;    
    }

             

    评论 2
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值