代码随想录【day 10 栈与队列】| 232.用栈实现队列、 225. 用队列实现栈

文章详细介绍了如何使用两个栈实现队列以及一个队列实现栈的数据结构操作,包括push、pop、peek和empty等方法。解题思路涉及在栈和队列特性基础上转换操作,实现队列的先进先出和栈的先进后出特性。同时,文章讨论了C++中STL的栈和队列容器适配器以及相关操作。
摘要由CSDN通过智能技术生成


理论基础

  • 栈和队列是STL(C++标准库)两个数据结构
  • 队列是先进先出
  • 栈是先进后出
    在这里插入图片描述
  • 栈提供push和pop等接口,所有元素必须符合先进后出规则,栈不提供走访功能,也不提供迭代器(iterator)。
  • 栈的底层实现可以是vector,deque,list

Q1: STL中栈和队列不被归类为容器,而被归类为container adapter(容器适配器)
Q2: 三个最为普遍的STL版本为HP STL 、P.J.Plauger STL、SGI STL(SGI STL是开源软件,源码可读性甚高)
Q3: 常用的SGI STL 如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构


LeetCode 232.用栈实现队列

题目链接:232.用栈实现队列
卡哥文解
视频讲解

题目描述: 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

  • 实现 MyQueue 类:
  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false
解题思路(两个栈模拟队列)

1、假设所有操作都是有效的(例如一个空的队列不会调用pop或者peek操作)
2、使用两个栈(in入栈 out出栈)实现队列先进先出的特点 注:将 入栈里 所有元素都放到 出栈里
3、push数据:只要数据放进 入栈 stIn.push(x);
4、pop元素:出栈如果为空 就把入栈数据全部导入,再从 出栈弹出栈顶元素 result = stOut.top(); 如果输出栈不为空,直接从出栈弹出数据。
5、判断队列为空:入栈和出栈都为空

实现难点

1、栈的标准操作包括
初始化一个栈 stack< int> stIn;
push元素 将对象压入栈顶 stIn.push(x);
判断为空 stIn.empty()
获得栈顶元素 stIn.top()
弹出栈顶元素 stIn.pop();
返回栈中元素的个数 stIn.size();
2、peek()的实现中复用了pop() (具体实现思路为先调用pop() 再将弹出的元素添加回去)
全局函数内无法直接调用struct类型变量内的成员,必须传一个struct指针(this指针
this->加上成员名 就是调用这个对象的成员

代码实现
class MyQueue {
public:
    // 初始化 入栈 & 出栈
    stack<int> stIn;
    stack<int> stOut;
    MyQueue() {

    }
    
    void push(int x) {
        stIn.push(x);
    }
    
    int pop() {
        // 当stOut为空 再从stIn导入数据
        if(stOut.empty()){
            while(!stIn.empty()){
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int result = stOut.top();
        stOut.pop();
        return result;
    }
    
    int peek() {
        int res = this->pop();
        stOut.push(res);
        return res;

    }
    
    bool empty() {
        return stIn.empty() && stOut.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

LeetCode 225. 用队列实现栈

题目链接:LeetCode225.用队列实现栈
卡哥文解
视频讲解
  • 题目描述: 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)
  • 实现 MyStack 类:
  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
解题思路(一个队列模拟栈)
  • 将队列头部元素(除最后一个元素外)重新添加到队列尾部
实现难点
  • C++ queue用法:只能访问queue的第一个和最后一个元素,只能在容器末尾添加新元素,只能从头部移除元素。
  • 移除第一个元素 que.pop();
  • 在尾部添加一个新的元素 que.push(x);
  • 访问第一个元素 que.front();
  • 访问最后一个元素 que.back()
代码实现
class MyStack {
public:
    // 初始化 队列
    queue<int> que;
    MyStack() {

    }
    
    void push(int x) {
        que.push(x);
    }
    
    int pop() {
        // 将队列头部元素(除最后一个元素外)重新添加到队列尾部
        int size = que.size();
        size--;
        while(size--){
            que.push(que.front());
            que.pop();
        }
        int result = que.front();
        que.pop();
        return result;
    }
    
    int top() {
        return que.back();
    }
    
    bool empty() {
        return que.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

day10总结复盘

1、之前对于队列和栈的理解只停留在先进先出以及先进后出的层面,写完这两题利用代码实现了一些基本操作 加深了理解
2、需要用两个栈来模拟队列,而可以只用一个队列来模拟栈。


补充

操作系统中堆(heap)和栈(stack)都是指内存空间。

  • 不同的堆为按需申请、动态分配,例如C中的malloc函数和C++中的new操作。(例如:p1 = (char *)malloc(10); )
  • 堆基本上可以理解为当前可以使用的空闲内存,但是其申请和释放都要程序员进行代码管理。(如果使用后忘记释放,会造成所谓的内存泄漏问题)
  • 栈是程序运行时自动拥有的一小块内存,由编译器自动分配释放,存放函数的参数值、局部变量的值(int a;)当这个局部变量离开其作用域后,所占用的内存就会自动释放。
  • 栈的空间有限制,一旦局部变量申请过多(例如开了超大数组),或者函数调用太深(例如递归太多次)就会导致栈溢出
  • 生长方向:堆生长(扩展)方向向上,向着内存地址增加的方向;栈生长(扩展)方向向下,向着内存地址减小的方向增长。
    参考文献
    https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
    https://zhuanlan.zhihu.com/p/88151799
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值