数据结构 ----栈和队列的相互实现


前言

栈(Stack)和队列(Queue)是两种常见的数据结构,它们在程序设计和算法中有着广泛的应用。栈和队列都是特定顺序的数据集合,但它们的操作方式和特性略有不同,因此在某些情况下,需要相互实现的能力。

有时候在解决问题时,需要将栈转换为队列或者队列转换为栈,以满足特定的操作顺序需求。例如,在某些算法中需要使用栈来辅助实现队列的功能,或者使用队列来实现栈的功能。这种转换可以通过两种数据结构的基本操作来实现,是算法设计中的常见技巧之一。

在接下来的讨论中,我们可以探讨如何实现栈和队列的相互转换,以及如何利用它们来解决各种实际问题。


一、思路

1.栈实现队列

(1).两个栈的定义:

in 栈:用于处理入队操作。新元素总是被压入 in 栈。
out 栈:用于处理出队和取队头操作。当需要从队列中移除元素或查看队头时,元素将从这个栈弹出。

(2).入队操作 (push):

新元素直接压入 in 栈。
出队操作 (pop):

如果 out 栈为空,则将 in 栈中的所有元素逐个弹出并压入 out 栈。这样,元素的顺序就被反转,使得最早进入 in 栈的元素现在位于 out 栈的顶部,这样可以实现队列的 FIFO 行为。如果 out 栈不为空,直接从 out 栈弹出元素。

(3)获取队头元素 (peek):

和 pop 类似,如果 out 栈为空,需要将 in 栈中的所有元素逐个弹出并压入 out 栈。
然后返回 out 栈的顶部元素,但不弹出它。
检查队列是否为空 (isEmpty):

只需检查 in 和 out 两个栈是否都为空。如果两个栈都为空,则队列为空。

2.队列实现栈

(1)Push 操作:

每次调用 push 方法时,将新元素添加到 queue2。
然后将 queue1 中的所有元素移动到 queue2。
最后交换 queue1 和 queue2,这样 queue1 中的元素顺序就变成了栈所需要的顺序。

(2)Pop 操作:

pop 方法直接从 queue1 中移除并返回元素,因为 queue1 中的顺序已经是栈的顺序。
Top 操作:

top 方法返回 queue1 的队首元素,这就是栈顶元素。

(3)Empty 操作:

empty 方法返回 queue1 是否为空。

二、详细代码

代码如下(示例):

import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    private Queue<Integer> queue;

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

    public void push(int x) {
        // Get the current size of the queue
        int size = queue.size();
        // Add the new element to the queue
        queue.offer(x);
        // Rotate the queue to make the newly added element at the front
        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();
    }

    public static void main(String[] args) {
        MyStack stack = new MyStack();
        stack.push(1);
        stack.push(2);
        System.out.println(stack.top());  // Output: 2
        System.out.println(stack.pop());  // Output: 2
        System.out.println(stack.top());  // Output: 1
        System.out.println(stack.empty()); // Output: false
    }
}


import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    private Queue<Integer> queue1;
    private Queue<Integer> queue2;

    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }

    // Push element x onto stack.
    public void push(int x) {
        // Add element to queue2
        queue2.offer(x);

        // Move all elements from queue1 to queue2
        while (!queue1.isEmpty()) {
            queue2.offer(queue1.poll());
        }

        // Swap the names of queue1 and queue2
        Queue<Integer> temp = queue1;
        queue1 = queue2;
        queue2 = temp;
    }

    // Removes the element on top of the stack and returns that element.
    public int pop() {
        // Remove and return the top element from queue1
        return queue1.poll();
    }

    // Get the top element.
    public int top() {
        // Return the top element without removing it
        return queue1.peek();
    }

    // Return whether the stack is empty.
    public boolean empty() {
        // Check if queue1 is empty
        return queue1.isEmpty();
    }

    public static void main(String[] args) {
        MyStack stack = new MyStack();
        stack.push(1);
        stack.push(2);
        System.out.println(stack.top());  // Output: 2
        System.out.println(stack.pop());  // Output: 2
        System.out.println(stack.top());  // Output: 1
        System.out.println(stack.empty()); // Output: false
    }
}




总结

1.用栈实现队列:使用两个栈来实现队列的功能,其中一个栈用于入队操作,另一个栈用于出队操作:这种方法保证了入队和出队操作的均摊时间复杂度为 O(1),虽然在某些情况下需要一定的操作来移动元素。
2. 用队列实现栈
使用两个队列来实现栈的功能,其中一个队列用于主要存储栈的元素,另一个队列在需要时辅助操作;这种实现方式同样保证了栈的基本操作的均摊时间复杂度为 O(1),虽然在某些情况下需要移动元素。

通过这种相互实现的方式,可以更深入地理解栈和队列的内部工作原理,加深对数据结构和算法的理解和运用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值