zoukankan      html  css  js  c++  java
  • 数据结构----------堆栈、队列补充

    数据结构----------堆栈、队列补充

    1. 两个队列实现一个栈

    • 基本思想:(总保证一个队列的数据为空)

        压栈:永远将数据添加到非空队列。

        弹栈:将n-1个元素出队,并添加到另外一个空的队列,然后poll第n个元素。

    • 代码实现
    import java.util.LinkedList;
    import java.util.Queue;
    /**
     * 
     *基于两个队列实现一个栈
     * @param <Item>
     */
    public class Stack<Item> {
        private Queue<Item> queue1 = new LinkedList<>();
        private Queue<Item> queue2 = new LinkedList<>();
        /**
         * 添加元素,每次都往不为空的队列中添加元素
         * @param item
         */
        public void push(Item item) {
            if(queue1.isEmpty()) {
                queue2.add(item);
                return;
            }
            if(queue2.isEmpty()) {
                queue1.add(item);
            }
        }
        
        
        /**
         * 弹出一个元素
         * @return
         */
        public Item pop() {
            if(queue1.isEmpty() && queue2.isEmpty()) {//如果俩个队列的数据都为空,刨出异常
                throw new RuntimeException("栈为空");
            }else if(queue1.isEmpty()) {//如果queue1为空,
                //将queue2的n-1个元素添加queue1
                while(queue2.size() > 1) {
                    queue1.add(queue2.poll());
                }
                //返回queue2的最后一个元素
                return queue2.poll();
            }else {//如果queue2为空
                //将queue1的n-1个元素添加的哦quque2
                while(queue1.size() > 1) {
                    queue2.add(queue1.poll());
                }
                //返回queue1的最后一个元素
                return queue1.poll();
            }        
        }
    }

    2. 两个栈实现一个队列

    • 基本思想

      入队:总是往第一个栈中添加数据

      出队:如果第二个栈数据不为空,咱弹栈元素即出队元素;如果第二栈的数据为空 ,则将n-1个元素弹出,并添加到第二个队列,然后弹出第一个栈的最后一个元素

      

    • 代码实现
      import java.util.Stack;
      /**
       * 两个栈实现一个队列
       * @author Administrator
       *
       * @param <Item>
       */
      public class Queue<Item> {
          private Stack<Item> stack1 = new Stack<>();
          private Stack<Item> stack2 = new Stack<>();
          
          /**
           * 入队 :全部添加到第一个栈
           * @param item
           */
          public void enqueue(Item item) {
              stack1.push(item);
          }
          
          /**
           * 出队:
           * @return
           */
          public Item dequeue() {
              if(stack2.size() != 0) {//如果第二个栈不为空,直接弹出
                  return stack2.pop();
              }else if(stack1.size() != 0) {//如果第二个栈为空,第一个栈不为空
                  //将n-1个元素压入第二个栈
                  while(stack1.size() > 1) {
                      stack2.push(stack1.pop());
                  }
                  //返回第一个栈的 最后一个元素
                  return stack1.pop();
              } else {//如果两个栈的数据 都为空
                  throw new RuntimeException("队列为空");
              }
          }
      }

    3. 实现一个能够返回最小元素的栈

      设计含最小函数min()的栈,要求min、push、pop、的时间复杂度都是O(1)。min方法的作用是:就能返回是栈中的最小值。

    • 基本思想

      一般情况下,我们可能会这么想:利用min变量,每次添加元素时,都和min元素作比较,这样的话,就能保证min存放的是最小值。但是这样的话,会存在一个问题:如果最小的元素出栈了,那怎么知道剩下的元素中哪个是最小的元素呢?

      改进思路:

       这里需要加一个辅助栈,用空间换取时间。辅助栈中,栈顶永远保存着当前栈中最小的数值。具体是这样的:原栈中,每次添加一个新元素时,就和辅助栈的栈顶元素相比较,如果新元素小,就把新元素的值放到辅助栈和原栈中,如果新元素大,就把元素放到原栈中;出栈时,如果原栈跟辅助栈元素相同,都弹出,否则只弹出原栈栈顶元素

    • 代码实现
      import java.util.Stack;
      
      public class MinStack<Item extends Comparable<Item>> {
          private Stack<Item> stack1 = new Stack<>();
          private Stack<Item> stackMin = new Stack<>();
          
          /**
           * 添加元素
           * @param item
           */
          public void push(Item item) {
              if(stack1.isEmpty()) {
                  stack1.push(item);
                  stackMin.push(item);
              }else {
                  Item minItem = stackMin.peek();
                  if(item.compareTo(minItem) < 0) {
                      stackMin.push(item);
                  }
                  stack1.push(item);
              }
          }
          
          public Item pop() {
              if(stack1.isEmpty()) {
                  throw new RuntimeException("栈为空");
              }
              if(stack1.peek().compareTo(stackMin.peek()) == 0) {
                  stackMin.pop();
              }
              return stack1.pop();
              
          }
          
          /**
           * 返回最小元素
           * @return
           */
          public Item min() {
              if(stackMin.isEmpty()) {
                  throw new RuntimeException("栈为空");
              }
              
              return stackMin.peek();
          }
      }
  • 相关阅读:
    c#使用NPOI导出Excel及往Excel里追加记录
    c#自定义进度条
    游戏中的过程生成——元胞自动机 Celluar Automata 生成洞穴地形
    在Unity(C#)下实现Lazy Theta*寻路
    A*算法改进——Any-Angle Path Planning的Theta*算法与Lazy Theta*算法
    unity下的Line of Sight(LOS)的绘制
    unity中绘制战争迷雾
    unet中可视性检查的一些笔记
    在DirectX11下用Stencil Buffer绘制可视化Depth Complexity
    漏洞复现-CVE-2015-1427-Groovy远程代码执行
  • 原文地址:https://www.cnblogs.com/gdy1993/p/9146025.html
Copyright © 2011-2022 走看看