队列

    • 队列使用
    • 实现队列
    • 循环数组实现队列
    • 两个队列实现栈
    • 两个栈实现队列

队列使用

队列:排队的队;想想坐高铁是不是排队;先进去的先出来。底层是通过链表实现的
队列_第1张图片
注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。
队列_第2张图片

实现队列

使用单向链表实现队列;为了让入队和出队时间复杂度都是O(1);增加一个tail引用
入队从tail的后面插入;进行尾插法

队列_第3张图片
出队从链表头部出队;进行删除链表头节点
队列_第4张图片
获取:
队列_第5张图片

循环数组实现队列

和多线程里的阻塞队列密切相关

public class test16 {//简单阻塞队列的实现;;先复习一遍循环队列
    private int[] elem;
    public int front;//队头
    public int rear;//队尾

    public test16(int k) {//创建这个对象,就有循环队列k大小数组
        elem=new int[k];
    }


    //判满;入队的前提条件,入队是满就直接返回。或者你在满的时候扩容,入之前判断是否满;如果满扩容再入
    public boolean isfull(){
        //怎么判;队尾+1 回到头。但是刚好队头在原点就会产生;位置相同;但是队尾+1的值不等于0.
        if((rear+1)%elem.length==front){
            return true;

        }
        return false;


    }
    //判空;出队的前提条件,出队是空直接返回
    public boolean isnull(){
 //对头==队就是空
        if(rear==front){
            return true;
        }
return false;

    }

    //入队方法;
public boolean offer1(int i) {
        if(isfull()){//满的情况返回入队失败

            return false;
        }
        //怎么入;是入在后面还是前面呢;队列尾入;这时候浪费的那个空间直接赋值进去;队尾往后移就好了
    elem[rear]=i;//会不会有点不合适;万一前面是没有元素呢
        rear=(rear+1)%elem.length;                  //这个队尾两种情况;第一种是单纯的加1;未到数组最后位置
                                                     //比如我把前面空间删除。刚好到最后一个位置;就得回归原点。%elem.length
                                                  
          //这里分开写效果会更好;rear++; if(rear>=elem.length){ rear=0; }
          //相比之下rear++;read=read%elem.length 。这个不易读,不直观;每次得理解好一会 。效率上又没有优势
                                                                             
        return true;

}




    //出队方法
    public Int poll1(){//头出、怎么出呢。感觉不合理;出队应该返回这个元素.所以得先记录
        if(isnull()){
            return -1;
        }
        int value=front;
     front=(front+1)%elem.length;//往后移一位;elem.length避免逛了一圈
        return elem[value];
    }
    //获取队首
  public int  peek1(){
        if(isnull()){
            return -1;
        }
 return elem[front];

  }
  //获取队尾
  public int  Rear(){
      if(isnull()){
          return -1;
      }
      //得注意;不能直接返回read-1.因为如果read是原点;那么减1不就变成负一
      if(rear==0){
          return elem[elem.length-1];
      }
      else
          return elem[rear-1];


  }

    public static void main(String[] args) {



    }
}

两个队列实现栈

入栈:入到不为空的队列中
出栈:找到不为空的队列;出size-1个元素到另一个队列当中去;剩下那个元素就是我们要出的元素。因为栈是先进后出。
队列_第6张图片
全部放进去后,然后就想想怎么出元素,(栈的出元素;弹出栈顶元素;最后进去的那一个;对于队列来说;最后进去的那一个是最后出来的;所以需要把前面的元素全部移到另一个队列里)
1:判断如果两个队列为空,则栈为空
2:如果有其中一个不为空,再把这个的size-1的元素扔到另一个空队列里去

队列_第7张图片
瞄一眼:
队列_第8张图片
整体代码:

//逻辑:先建两个队;然后入队:入都不为空的队列(都为空默认放队1)
  //    出队:把size-1全部丢掉另一个空队。然后剩下一个元素,这个元素就是我们最后进去的元素,先出。这就是栈的规则
 //窥视:全部放到另一个队列里,  每次循环放进去都记录下来 ret = qu1.poll();反正到时候会更新记录到的是最后一个。栈顶元素

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

class MyStack {

    private Queue<Integer> qu1;
    private Queue<Integer> qu2;

    public MyStack() {
        qu1 = new LinkedList<>();
        qu2 = new LinkedList<>();
    }
    
    public void push(int x) {
        if(!qu1.isEmpty()) {
            qu1.offer(x);
        }else if(!qu2.isEmpty()) {
            qu2.offer(x);
        }else {
            //两个队列都为空的时候
            qu1.offer(x);
        }
    }
    
    public int pop() {
        if(empty()) {
            return -1;//
        }
        if(!qu1.isEmpty()) {
            int size = qu1.size();
            for (int i = 0; i < size-1; i++) {

                qu2.offer(qu1.poll());
            }
            return qu1.poll();
        }else {
            int size = qu2.size();
            for (int i = 0; i < size-1; i++) {

                qu1.offer(qu2.poll());
            }
            return qu2.poll();
        }
    }
    //peek
    public int top() {
        if(empty()) {
            return -1;//
        }
        if(!qu1.isEmpty()) {
            int size = qu1.size();
            int ret = -1;
            for (int i = 0; i < size; i++) {
                ret = qu1.poll();
                qu2.offer(ret);
            }
            return ret;
        }else {
            int size = qu2.size();
            int ret = -1;
            for (int i = 0; i < size; i++) {
                ret =  qu2.poll();
                qu1.offer(ret);
            }
            return ret;
        }
    }

    //两个队列都为空 那么就是栈为空
    public boolean empty() {
        return qu1.isEmpty() && qu2.isEmpty();
    }
}

两个栈实现队列

入队时放到栈1;出队时从栈2出。如果栈2是空;就把栈1的元素倒进栈2

import java.util.Stack;

class MyQueue2 {

    private Stack<Integer> s1;
    private Stack<Integer> s2;
    public MyQueue2() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    
    public void push(int x) {
        s1.push(x);
    }

    //
    public int pop() {
        if(empty()) {
            return -1;
        }
        if(s2.empty()) {
            while (!s1.empty()) {
                s2.push(s1.pop());
            }
        }
        //
        return s2.pop();
    }
    
    public int peek() {
        if(empty()) {
            return -1;
        }
        if(s2.empty()) {
            while (!s1.empty()) {
                s2.push(s1.pop());
            }
        }
        //
        return s2.peek();
    }

    //如果两个栈 都是空的 呢么队列就是空的
    public boolean empty() {
        return s1.empty() && s2.empty();
    }
}

你可能感兴趣的:(数据结构,java,开发语言)