代码随想录day10 栈与队列 || 用队列实现栈、用栈实现队列


学习栈和队列需要先熟悉栈和队列相应的性质和各自的方法。

栈(Stack)是一种常见的数据结构,它遵循先进后出(Last-In-First-Out,LIFO)的原则。可以将栈看作是一叠盘子,只能从最顶层放入和取出元素,无法直接访问或修改中间位置的元素。

栈的主要操作包括以下方法:

  • push(E element):将元素压入栈顶。新的元素被添加到栈的顶部,成为新的栈顶元素。

  • pop():弹出栈顶元素并返回。栈顶元素被移除,并且返回被移除的元素。

  • peek():返回栈顶元素,但不进行移除。只返回栈顶的元素,不对栈进行修改。

  • isEmpty():检查栈是否为空。如果栈中没有任何元素,返回 true;否则返回 false。

栈的实现可以使用数组或链表等数据结构。在实际编程中,常用的栈实现方式包括使用数组或使用链表,也可以使用现有的栈数据结构(如C++中的std::stack、Java中的java.util.Stack)。

栈常用于解决与后续处理(如函数调用、表达式求值、回溯算法等)相关的问题,也可用于处理需要遵循 LIFO 原则的其他情况。

队列

队列(Queue)是一种常见的数据结构,它遵循先进先出(First-In-First-Out,FIFO)的原则。可以将队列看作是一条排队等候的队伍,新的元素被添加到队列的末尾,而从队列中取出元素的操作总是从队列的头部进行。

队列的主要操作包括以下方法:

  1. add(E element):将元素添加到队列的末尾。如果队列已满则抛出异常。

  2. offer(E element):将元素添加到队列的末尾。如果队列已满则返回 false

  3. remove():移除并返回队列头部的元素。如果队列为空则抛出异常。

  4. poll():移除并返回队列头部的元素。如果队列为空则返回 null

  5. element():返回队列头部的元素,但不进行移除操作。如果队列为空则抛出异常。

  6. peek():返回队列头部的元素,但不进行移除操作。如果队列为空则返回 null

  7. int size():返回队列中元素的数量。该方法返回队列的当前大小,即队列中包含的元素个数。

  8. boolean isEmpty():检查队列是否为空。如果队列中没有任何元素,即队列为空,返回 true;否则返回 false。.

队列的实现可以使用数组、链表或其他数据结构。在实际编程中,常用的队列实现方式包括使用数组、使用链表或使用现有的队列数据结构(如C++中的std::queue、Java中的java.util.Queue)。

队列常用于处理需要遵循 FIFO 原则的场景,例如任务调度、消息传递、广度优先搜索等。它可以确保元素按照添加的顺序被处理,并且适用于多线程环境下的并发操作。

232. 用栈实现队列

class MyQueue {
    private Stack<Integer> stackIn;
    private Stack<Integer> stackOut;

    public MyQueue() {
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        int peek = peek();
        stackOut.pop();
        return peek;
    }
    
    public int peek() {
        if(!stackOut.isEmpty()){
            return stackOut.peek();
        }
        while(!stackIn.isEmpty()){
            stackOut.push(stackIn.pop());
        }
        return stackOut.peek();
    }
    
    public boolean empty() {
        if(stackIn.isEmpty() && stackOut.isEmpty()){
            return true;
        }
        return false;
    }
}

225. 用队列实现栈

双队列模拟栈

定义两个队列A与B,其中A是模拟的栈,B队列是备份队列。在添加元素时,先把元素添加到队列B中,然后再循环将A队列的值都出队并添加到B队列末尾。这样,每次添加元素之后,B队列中的元素都是以出栈的顺序排列的。循环结束后,将B队列赋值给A队列,B队列置为空,等待下一次添加元素。
这样处理过后,A队列中的元素都是以栈的出栈顺序排列的,如果要获取栈顶元素或出栈,直接执行A队列的方法即可。

class MyStack {
    Queue<Integer> Queue1;
    Queue<Integer> Queue2;

    public MyStack() {
        Queue1 = new LinkedList<Integer>();
        Queue2 = new LinkedList<Integer>();
    }
    
    public void push(int x) {
        Queue2.offer(x);
        while(!Queue1.isEmpty()){
            Queue2.offer(Queue1.poll());
        }
        Queue<Integer> temp = Queue1;
        Queue1 = Queue2;
        Queue2 = temp;
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int top() {
        return queue1.peek();
    }
 
    public boolean empty() {
        return queue1.isEmpty();
    }
}

用一个队列实现栈

将上述方法进行优化,我们可以不需要备份队列B,元素入栈时,将它添加到队列A队尾,然后再将之前的所有元素依次出队并添加到队尾,此时元素就已排列成出栈的顺序。然后直接对队列A进行栈操作即可。

class MyStack {
    Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<Integer>();
    }
    
    public void push(int x) {
        int size = queue.size();
        queue.offer(x);
        for(int i = 0; i < size; i++){
            queue.offer(queue.poll());
        }
    }
    
    public int pop() {
        return queue.poll();
    }
    
    public int top() {
        return queue.peek();
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值