13.【入门】队列和栈入门题目-栈和队列相互实现

本文的网课内容学习自B站左程云老师的算法详解课程,旨在对其中的知识进行整理和分享~

网课链接:算法讲解014【入门】队列和栈入门题目-栈和队列相互实现_哔哩哔哩_bilibili

一.利用栈实现队列

题目:用栈实现队列

算法原理

一、数据结构定义
  • 两个栈
    • 这个算法使用了两个栈,分别是in栈和out栈。
    • MyQueue类中定义为public Stack<Integer> in;public Stack<Integer> out;。这两个栈用于存储数据,模拟队列的操作。
二、构造函数
  • 初始化
    • MyQueue的构造函数public MyQueue()中,分别初始化了in栈和out栈,创建了两个空的栈,为后续操作做准备。
三、inToOut方法(数据转移操作)
  • 转移条件
    • 这个方法的目的是将in栈中的数据转移到out栈中。
    • 转移的条件有两个:
      • 首先,out栈必须为空(if (out.empty())),这样可以保证数据的顺序是按照队列先进先出的原则。如果out栈不为空,说明之前已经有数据在out栈中等待出队,不需要从in栈转移数据。
      • 其次,一旦开始转移数据,就要将in栈中的数据全部转移完(while (!in.empty()))。这是因为队列的先进先出特性,要保证先进入队列的数据先出队。
    • 在转移数据时,从in栈弹出数据(in.pop()),然后将弹出的数据压入out栈(out.push())。
四、push方法(入队操作)
  • 入队操作
    • push方法中,首先将元素x压入in栈(in.push(x))。
    • 然后调用inToOut方法,这个调用的目的是为了在入队操作后,检查是否需要将in栈中的数据转移到out栈中,以保持队列的顺序。
五、pop方法(出队操作)
  • 出队操作
    • 首先调用inToOut方法,确保数据在正确的栈中。如果out栈为空,这个方法会将in栈中的数据转移到out栈中。
    • 然后从out栈弹出一个元素(return out.pop()),这模拟了队列的出队操作,即取出最先进入队列的元素。
六、peek方法(查看队首元素操作)
  • 查看队首元素操作
    • 同样先调用inToOut方法,保证数据顺序正确。
    • 然后返回out栈的栈顶元素(return out.peek()),这个操作只是查看队首元素,而不将其从队列中移除。
七、empty方法(判断队列是否为空操作)
  • 判断队列是否为空操作
    • 这个方法通过检查in栈和out栈是否都为空(return in.isEmpty() && out.isEmpty())来判断整个队列是否为空。如果两个栈都为空,说明队列中没有元素。

代码实现

//利用栈实现队列
// 测试链接 : https://leetcode.cn/problems/implement-queue-using-stacks/
class MyQueue {

    public Stack<Integer> in;

    public Stack<Integer> out;

    public MyQueue() {
        in = new Stack<Integer>();
        out = new Stack<Integer>();
    }

    // 倒数据
    // 从in栈,把数据倒入out栈
    // 1) out空了,才能倒数据
    // 2) 如果倒数据,in必须倒完
    private void inToOut() {
        if (out.empty()) {
            while (!in.empty()) {
                //将in中弹出的数据压入out中
                out.push(in.pop());
            }
        }
    }

    public void push(int x) {
        in.push(x);
        inToOut();
    }

    public int pop() {
        inToOut();
        return out.pop();
    }

    public int peek() {
        inToOut();
        return out.peek();
    }

    public boolean empty() {
        return in.isEmpty() && out.isEmpty();
    }

}

二.利用队列实现栈

1.题目:用队列实现栈

算法原理

一.push操作原理
  • 当执行push操作时,首先记录当前队列queue的大小n
  • 然后将新元素x添加到队列末尾。
  • 接着,通过循环n次,每次将队列头部的元素取出并重新添加到队列末尾。这样做的目的是将新添加的元素x移动到队列的头部,从而模拟栈的后进先出(LIFO)特性。因为经过这一系列操作后,新元素x成为了队列中最先被取出的元素,就像栈顶元素一样。
二.pop操作原理
  • pop操作直接调用队列的poll方法。由于push操作已经将新元素移动到队列头部(如果是最后一个被push进去的元素),所以poll操作会取出这个相当于栈顶的元素,符合栈的弹出操作逻辑。
三.top操作原理
  • top操作调用队列的peek方法。peek方法返回队列头部的元素但不删除它,由于push操作保证了最后push进去的元素在队列头部,所以这个操作返回的就是相当于栈顶的元素。
四.empty操作原理
  • empty操作直接调用队列的isEmpty方法,用于判断栈是否为空。因为这个基于队列实现的栈的数据都存储在队列中,所以当队列空时,栈也是空的。

代码实现

class MyStack {

        Queue<Integer> queue;

        public MyStack() {
            queue = new LinkedList<Integer>();
        }

        // O(n)
        public void push(int x) {
            int n = queue.size();
            queue.offer(x);
            for (int i = 0; i < n; i++) {
                queue.offer(queue.poll());
            }
        }

        public int pop() {
            return queue.poll();
        }

        public int top() {
            return queue.peek();
        }

        public boolean empty() {
            return queue.isEmpty();
        }

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值