(队列&栈)用队列实现栈/用栈实现队列---数据结构

89 篇文章 0 订阅
38 篇文章 1 订阅
本文介绍了如何仅使用两个队列实现一个后入先出(LIFO)的栈,以及如何仅使用两个栈实现一个先入先出(FIFO)的队列。通过巧妙的元素转移策略,模拟了栈和队列的基本操作,如push、pop、top和empty。这两个实现展示了数据结构的灵活性和创造性。
摘要由CSDN通过智能技术生成
  • 用队列实现栈
    要求:
    仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通队列的全部四种操作(push、top、pop 和 empty)
    说明:
    (1)只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
    (2)所使用的语言也许不支持队列,可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
    思路:操作前始终保持一个队列是空的。相互来回“倒腾”,以此达到模拟栈只允许在一端进行插入和删除操作的目的。
    实现:
import java.util.LinkedList;
import java.util.Queue;


public class MyStack {
    private Queue<Integer> queue1 = new LinkedList<>();//定义两个队列
    private Queue<Integer> queue2 = new LinkedList<>();

    public static void main(String[] args) {
        MyStack stack=new MyStack();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack.pop());//3
        System.out.println(stack.pop());//2
        stack.push(4);
        System.out.println(stack.top());//4
        System.out.println(stack.empty());//false
    }
    public void push(int x) {//模拟压栈
        Queue<Integer> queue;
        if (!queue1.isEmpty()) {
            queue = queue1;
        } else if (!queue2.isEmpty()) {
            queue = queue2;
        } else {
            queue = queue2;
        }
        queue.add(x);
    }

    public int pop() {//模拟出栈
        Queue<Integer> queue;//指向不为空的队列
        Queue<Integer> toQueue;//指向为空的队列
        if (!queue1.isEmpty()) {
            queue = queue1;
            toQueue = queue2;
        } else {
            queue = queue2;
            toQueue = queue1;
        }
        int size = queue.size();
        for (int i = 0; i < size - 1; i++) {
            int e = queue.remove();
            toQueue.add(e);//把不为空队列中除最后一个元素以外的其他元素全部移动到空的那个队列中
        }
        return queue.remove();//最后一个元素出队列 实现了后进先出
    }

    public int top() {//模拟拿到栈顶元素
        Queue<Integer> queue;
        Queue<Integer> toQueue;
        if (!queue1.isEmpty()) {
            queue = queue1;
            toQueue = queue2;
        } else {
            queue = queue2;
            toQueue = queue1;
        }
        int size = queue.size();
        for (int i = 0; i < size - 1; i++) {
            int e = queue.remove();
            toQueue.add(e);
        }
        return queue.remove();
    }

    public boolean empty() {//模拟栈是否为空
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

执行结果:
在这里插入图片描述

  • 用栈实现队列
    要求:
    仅使用两个栈实现先入先出队列,队列应当支持一般队列支持的所有操作(push、pop、peek、empty)。
    说明:
    (1)只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
    (2)所使用的语言也许不支持栈,可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
    思路:
    因为栈只允许在固定的一端进入插入和删除,所有元素入栈只在一个队列里,保持一个栈为空,出栈时把所有元素从栈1出,栈2入,再栈2出,其顺序就与队列相符。
    实现:
import java.util.Stack;

public class SQueue {
    public static void main(String[] args) {
        SQueue q = new SQueue();
        q.push(1);
        q.push(2);
        q.push(3);
        System.out.println(q.pop());//1
        System.out.println(q.pop());//2
        q.push(4);
        System.out.println(q.peek());//3
        System.out.println(q.empty());//false
    }

    Stack<Integer> stack1 = new Stack<>();
    Stack<Integer> stack2 = new Stack<>();

    public void push(int x) {//将元素 x 推到队列的末尾
        stack2.push(x);
    }

    public int pop() {//从队列的开头移除并返回元素
        if (stack1.isEmpty()) {
            while (!stack2.isEmpty()){
                int e=stack2.pop();
                stack1.push(e);
            }
        }
        return stack1.pop();
    }
    public int peek(){//返回队列开头的元素
        if (stack1.isEmpty()){
            while (!stack2.isEmpty()){
                int e=stack2.pop();
                stack1.push(e);
            }
        }
        return stack1.peek();
    }
    public boolean empty(){
        return stack1.isEmpty()&&stack2.isEmpty();
    }
}

执行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值