代码随想录算法训练营Day10|232.用栈实现队列、225用队列实现栈 C++

栈和队列

        栈是一种FILO(first in last out)先进后出的数据结构,即先进入栈的数据会保存在靠近栈底的位置,而后进入的数据会离栈顶更近,而栈顶是唯一的数据出口,先进入的数据后出,后进入的数据先出,一个形象的表示,当你去买书时,在一摞相同的书中,最方便的方式会选择购买最上层的书,这摞书就是一个栈,先进后出。

        栈的定义

        栈是一种特殊的线性表,其插入(也称为入栈或压栈)和删除(也称为出栈或弹栈)操作都在表的同一端进行。这一端称为栈顶(top),另一端称为栈底(bottom)

        由于栈是一种特殊的线性表,所以从相应的线性表类(数组和链表)派生出栈类是非常正常的事情。所以可以通过数组和链表实现的栈,在C++的STL库中,栈的底层实现可以是vector、deque和list等,而由于是运用其他容器进行实现,STL中的栈往往不被归类为容器,而被归类为container adapter(容器适配器)。

        队列是一种FIFO(first in first out)先进先出的数据结构,一个简单的举例,在银行窗口前的排队,先排队的人先服务,后到的人需要等待。

        队列的定义:队列是一个线性表,其插入和删除操作分别在表的不同端进行。插入元素的那一段称为队尾(back或rear),删除元素的那一端称为队首(front)

        同样队列也可以从相应的线性表类中派生出,所以,它也被归类为容器适配器。

用栈实现队列

        题目要求仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty),这些操作分别表示,将元素x放入队尾、从队头取出元素、返回队头的元素、判断队列是否为空。

        首先要求是通过两个栈实现先入先出队列,栈是后入先出的数据结构,想要将后入先出的栈组成一个先入先出的队列,一个简单的思路是将元素全部入栈到栈1,在需要弹出数据时,将所有数据的出栈到栈2中,再从栈2出弹出数据,此时的数据就是最先进入栈1的数据。即实现了数据的先入先出。

class MyQueue {
private:
    stack<int>stackin,stackout;//创建2个栈stackin和stackout
public:
    MyQueue() {

    }
    
    void push(int x) {//若stackout非空,将所有的元素搬回出栈,入栈到stackin,然后push
        while(!stackout.empty()){
            stackin.push(stackout.top());
            stackout.pop();
        }
        stackin.push(x);
    }
    
    int pop() {//若stackin非空,将stackin中所有元素入栈到stackout中,stackout出栈
         while(!stackin.empty()){
            stackout.push(stackin.top());
            stackin.pop();
        }
        int x = stackout.top();
        stackout.pop();
        return x;
    }
    
    int peek() {//同pop,不过返回的是stackout.top().
        while(!stackin.empty()){
            stackout.push(stackin.top());
            stackin.pop();
        }
        return stackout.top();
    }
    
    bool empty() {//当stackin和stackout皆空,则为空,否则非空
        return(stackin.empty() and stackout.empty());
    }
};

        这里有一个问题在于每次pop和push都需要频繁的入栈和出栈,实际上,当stackout非空时,push操作只需要stackin.push(x)就行,而当要pop时,判断stackout.empty(),若为空,将stackin中所有元素入栈到stackout中,即能省去一些没必要的操作。时间复杂度push、pop和peek都为O(n),empty的时间复杂度为O(1),空间复杂度均为O(1)。

用队列实现栈

        题目要求用两个队列来模拟栈,此时由于队列这个数据结构的先入先出的特点,并不能用前面用栈实现队列那样来回倒的方式实现栈,考虑栈的先进后出特性,当第一个队列出到只剩最后一个元素时,即为栈中最先出的元素,可以考虑创建两个队列,一个队列用于出最后一个元素,另外一个队列用于存放前面的所有元素。通过队列模拟栈的代码如下:

class MyStack {
private:
    queue<int> stack;//创建模拟栈的队列
    queue<int>backups;//创建备份队列
public:
    MyStack() {

    }
    
    void push(int x) {
        stack.push(x);
    }
    
    int pop() {
        while(stack.size()!=1){
        backups.push(stack.front());
        stack.pop();
        }
        int x = stack.front();
        stack.pop();
        while(backups.size()){
            stack.push(backups.front());
            backups.pop();
        }
        return x;
    }
    
    int top() {
        while(stack.size()!=1){
        backups.push(stack.front());
        stack.pop();
        }
        int temp = stack.front();
        backups.push(stack.front());//注意这里要将所有的元素全放进backups再重新恢复stack队列
        stack.pop();
        while(backups.size()!=0){
            stack.push(backups.front());
            backups.pop();
        }
        return temp;
    }
    
    bool empty() {
        return(stack.empty());//当栈队列为空,则为空,因为每次都会复原
    }
};

        这里的一个点在于top操作,需要记住将所有stack队列中的元素都放进backup队列中,再考虑将backup中元素重新放回stack中。即每次复原stack队列前要确保stack队列为空,否则会导致乱序。push的时间复杂度为O(1),pop()、top()的时间复杂度为O(n),空间复杂度为O(n)。

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值