Java 栈和队列的交互实现

 更新时间:2023年12月21日 11:22:15   作者:爱吃南瓜的北瓜  
栈和队列都是常用的数据结构,本文就来介绍一下Java 栈和队列的交互实现,主要包括队列模拟实现栈及栈模拟实现队列,具有一定的参考价值,感兴趣的可以了解一下

队列和栈的区别

栈和队列都是常用的数据结构,它们的主要区别在于数据的插入和删除顺序。

栈 (Stack) 是一种后进先出 (Last-In-First-Out, LIFO) 的数据结构,只允许在一端进行插入和删除操作,这一端称为栈顶。新元素插入后成为新的栈顶,而删除时也只能删除栈顶元素。

队列 (Queue) 是一种先进先出 (First-In-First-Out, FIFO) 的数据结构,允许在两端进行插入和删除操作,插入在队尾,删除在队头。新元素插入时成为新的队尾,而删除时也只能删除队头元素。

一.用队列模拟实现栈

1.void push(int x) 将元素 x 压入栈顶。
2.int pop() 移除并返回栈顶元素。
3.int top() 返回栈顶元素。
4.boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

如上便是需要用队列来实现栈的四个基本操作。
我们试想,实现这些栈的操作,一个队列可以完成吗?
显然不可以,我们使用两个队列来实现栈的模拟

在这里插入图片描述

大体流程
1.入栈时:
如果两个都为空,那么想

1.1入栈

当我们要放入18 25 35 48 这一串数字入栈时,先放入18 25 35(放入时选择的队列是不为空的队列),模拟入队以及入栈时的状况,如下图

在这里插入图片描述

 public void push(int x) {
        if(empty()){
            queue1.offer(x);
            return;
        }
        if(!queue1.isEmpty()){
            queue1.offer(x);
        }else {
            queue2.offer(x);
        }
    }

1.2出栈

此时如果我们要将35出栈时,又该如何操作呢?此时我们就需要用到第二个队列,将队列一的前size-1个元素(也就是18 25)从队列一中出队,放入队列二中。此时队列一中的元素为35,队列二的元素为18 25 如下图。

在这里插入图片描述

当初栈完成时,我们此时要将48入栈时,又该放入哪个栈中呢?我们考虑栈的特点(先入后出),我们将再入栈的元素放到不为空的队列中。

在这里插入图片描述

 public int pop() {
        if(empty()){
            return -1;
        }
        if(!queue1.isEmpty()){
            int size = queue1.size();
            for (int i = 0; i < size-1; i++) {
                queue2.offer(queue1.poll());
            }
            return queue1.poll();
        }else {
            int size = queue2.size();
            for (int i = 0; i < size-1; i++) {
                queue1.offer(queue2.poll());
            }
            return queue2.poll();
        }
    }

1.3返回栈顶元素

在实现pop的基础上,我们将声明一个变量temp来储存每次要移除的元素。

  public int top() {
        if(empty()){
            return -1;
        }
        if (!queue1.isEmpty()){
            int temp = -1;
            int size = queue1.size();
            for (int i = 0; i < size; i++) {
                temp = queue1.poll();
                queue2.offer(temp);
            }
            return temp;
        }else {
            int size = queue2.size();
            int temp = -1;
            for (int i = 0; i < size; i++) {
                temp = queue2.poll();
                queue1.offer(temp);
            }
            return temp;
        }
    }

1.4判断栈是否为空

当队列一和队列二都为空时,此时栈就为空。

public boolean empty() {
        return queue1.isEmpty()&&queue2.isEmpty();
    }

二.用栈模拟实现队列

我们也是用两个栈来模拟实现队列

2.1 入队

我们将所有入队的元素都放入栈一中,如下图

在这里插入图片描述

public void push(int x) {
          stack1.push(x);
    }

2.2出队

要出栈时,如果栈二不为空,就出栈二中的元素,如果栈二为空,将栈一中的所有元素一次性的全部push到栈二中,此时就将入栈的元素全部倒转过来了,(例如入栈时在栈中的入栈顺序依次排序为18 25 35,栈二中此时的元素入栈顺序是35 25 18,出栈时就先出18,就完成了转换)如下图

在这里插入图片描述

 public int pop() {
           if(empty()){
               return -1;
           }
           if (stack2.isEmpty()){
               while (!stack1.isEmpty()){
                   stack2.push(stack1.pop());
               }
           }
           return stack2.pop();
    }

2.3peek

peek只是将出队时的pop换成peek,就可以完成要求。

public int peek() {
        if(empty()){
            return -1;
        }
        if (stack2.isEmpty()){
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }

2.4判断队列是否为空

如果栈一和栈二都为空时,那么队列就为空。

 public boolean empty() {
          return stack1.isEmpty() && stack2.isEmpty();
    }

三.完整代码

3.1 队列模拟实现栈

class MyStack {

    Queue<Integer> queue1 ;
    Queue<Integer> queue2 ;
    public MyStack() {
         queue1 = new LinkedList<>();
         queue2 = new LinkedList<>();
    }
    public void push(int x) {
        if(empty()){
            queue1.offer(x);
            return;
        }
        if(!queue1.isEmpty()){
            queue1.offer(x);
        }else {
            queue2.offer(x);
        }
    }

    public int pop() {
        if(empty()){
            return -1;
        }
        if(!queue1.isEmpty()){
            int size = queue1.size();
            for (int i = 0; i < size-1; i++) {
                queue2.offer(queue1.poll());
            }
            return queue1.poll();
        }else {
            int size = queue2.size();
            for (int i = 0; i < size-1; i++) {
                queue1.offer(queue2.poll());
            }
            return queue2.poll();
        }
    }

    public int top() {
        if(empty()){
            return -1;
        }
        if (!queue1.isEmpty()){
            int temp = -1;
            int size = queue1.size();
            for (int i = 0; i < size; i++) {
                temp = queue1.poll();
                queue2.offer(temp);
            }
            return temp;
        }else {
            int size = queue2.size();
            int temp = -1;
            for (int i = 0; i < size; i++) {
                temp = queue2.poll();
                queue1.offer(temp);
            }
            return temp;
        }
    }

    public boolean empty() {
        return queue1.isEmpty()&&queue2.isEmpty();
    }
}

3.2栈模拟实现队列

class MyQueue {
    public Stack<Integer> stack1 ;
    public Stack<Integer> stack2;
    public MyQueue() {
     stack1 = new Stack<>();
     stack2 = new Stack<>();
    }

    public void push(int x) {
          stack1.push(x);
    }

    public int pop() {
           if(empty()){
               return -1;
           }
           if (stack2.isEmpty()){
               while (!stack1.isEmpty()){
                   stack2.push(stack1.pop());
               }
           }
           return stack2.pop();
    }

    public int peek() {
        if(empty()){
            return -1;
        }
        if (stack2.isEmpty()){
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }

    public boolean empty() {
          return stack1.isEmpty() && stack2.isEmpty();
    }
}

到此这篇关于Java 栈和队列的交互实现的文章就介绍到这了,更多相关Java 栈和队列交互内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • IDEA的.idea文件夹和iml文件使用方式

    IDEA的.idea文件夹和iml文件使用方式

    这篇文章主要介绍了IDEA的.idea文件夹和iml文件使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Eclipse/MyEclipse转IntelliJ IDEA完全攻略(图文)

    Eclipse/MyEclipse转IntelliJ IDEA完全攻略(图文)

    这篇文章主要介绍了Eclipse/MyEclipse转IntelliJ IDEA完全攻略(图文),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • jdbc中class.forname的作用

    jdbc中class.forname的作用

    这篇文章主要介绍了jdbc中class.forname的作用,使用示例说明了他作用及使用方法,大家参考使用吧
    2014-01-01
  • mybatis-generator自动生成dao、mapping、bean配置操作

    mybatis-generator自动生成dao、mapping、bean配置操作

    这篇文章主要介绍了mybatis-generator自动生成dao、mapping、bean配置操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • java面试常见问题之Hibernate总结

    java面试常见问题之Hibernate总结

    这篇文章主要介绍了在java面试过程中hibernate比较常见的问题,包括Hibernate的检索方式,Hibernate中对象的状态,Hibernate的3种检索策略是什么,Session的find()方法以及Query接口的区别等方面问题的总结,需要的朋友可以参考下
    2015-07-07
  • Java基于余弦方法实现的计算相似度算法示例

    Java基于余弦方法实现的计算相似度算法示例

    这篇文章主要介绍了Java基于余弦方法实现的计算相似度算法,简单说明了余弦相似性的概念、原理并结合实例形式分析了java实现余弦相似性算法的相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • spring如何使用命名空间p简化bean的配置

    spring如何使用命名空间p简化bean的配置

    这篇文章主要介绍了spring如何使用命名空间p简化bean的配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java源码解析阻塞队列ArrayBlockingQueue介绍

    Java源码解析阻塞队列ArrayBlockingQueue介绍

    今天小编就为大家分享一篇关于Java源码解析阻塞队列ArrayBlockingQueue介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • JavaScript中的Map用法完全指南

    JavaScript中的Map用法完全指南

    这篇文章主要介绍了JavaScript中Map用法的相关资料,通过实例讲解了Map的创建、常用方法和迭代方式,还探讨了Map与对象的区别,并通过一个例子展示了如何使用Map来统计字符出现的次数,需要的朋友可以参考下
    2025-03-03
  • java如何实现获取客户端ip地址的示例代码

    java如何实现获取客户端ip地址的示例代码

    本文主要介绍了java如何实现获取客户端ip地址,主要包括java获取客户端ip地址工具类使用实例、应用技巧,文中通过示例代码介绍的非常详细,感兴趣的小伙伴们可以参考一下
    2022-04-04

最新评论