数组模拟队列和环形队列——韩顺平java数据结构系列(二)

数组模拟普通队列

数组模拟队列和环形队列——韩顺平java数据结构系列(二)_第1张图片
代码:

public class ArrayQueue {
  private final int maxSize; // 数组最大容量
  private int front; // 队首,指向队列头部元素的前一个位置(不包含)
  private int rear; // 队尾,指向队列末尾元素(含队尾元素)
  private final int[] arr; // 队列数组

  // 队列构造器
  public ArrayQueue(int maxSize) {
    this.maxSize = maxSize;
    arr = new int[maxSize];
    // 指针初始化
    front = rear = -1;
  }

  // 判断队列是否满
  public boolean isFull() {
    return rear == maxSize - 1;
  }

  // 判断队列是否空
  public boolean isEmpty() {
    return rear == front;
  }

  // 添加数据到队列
  public void addQueue(int elem) {
    if (isFull()) {
      System.out.println("队列满");
      return;
    }
    rear++; // 让rear后移
    arr[rear] = elem;
  }

  // 出队
  public int getQueue() {
    if (isEmpty()) {
      throw new RuntimeException("队列空");
    }
    front++; // front 后移动
    return arr[front];
  }

  public void showQueue() {
    if(isEmpty()) {
      System.out.println("[ ]");
      return;
    }
    System.out.print("[ ");
    for (int i = front+1; i < rear+1; i++) {
      System.out.printf(" %d ", arr[i]);
    }
    System.out.print(" ]\n");
  }

  // 显示队首数据,不取出
  public int peekQueue() {
    if (isEmpty()) {
      throw new RuntimeException("队列空");
    }
    return arr[front+1];
  }

}

数组模拟环形队列

数组模拟队列和环形队列——韩顺平java数据结构系列(二)_第2张图片
数组模拟队列和环形队列——韩顺平java数据结构系列(二)_第3张图片
数组模拟队列和环形队列——韩顺平java数据结构系列(二)_第4张图片
数组模拟队列和环形队列——韩顺平java数据结构系列(二)_第5张图片
代码:

public class CircleArrayQueue {
  private final int maxSize; // 数组最大容量
  private int front; // 队首,指向队列头部元素(包含)
  private int rear; // 队尾,指向队列末尾元素后一个位置(不包含队尾)
  private final int[] arr; // 队列数组

  // 队列构造器
  public CircleArrayQueue(int maxSize) {
    this.maxSize = maxSize;
    arr = new int[maxSize];
    // 指针初始化
    front = rear = 0;
  }

  // 判断队列是否满
  public boolean isFull() {
    return (rear + 1) % maxSize == front;
  }

  // 判断队列是否空,代码没变
  public boolean isEmpty() {
    return rear == front;
  }

  // 添加数据到队列
  public void addQueue(int elem) {
    if (isFull()) {
      System.out.println("队列满");
      return;
    }
    // 直接加入数据
    arr[rear] = elem;
    rear = (rear + 1) % maxSize;
  }

  // 出队
  public int getQueue() {
    if (isEmpty()) {
      throw new RuntimeException("队列空");
    }
    // front直接取值
    int val = arr[front];
    // + 1 取模
    front = (front + 1) % maxSize;
    return val;
  }

  public void showQueue() {
    if(isEmpty()) {
      System.out.println("[ ]");
      return;
    }
    System.out.print("[ ");
    for (int i = front; i < front + size(); i++) {
      System.out.printf(" %d ", arr[i % maxSize]);
    }
    System.out.print(" ]\n");
  }

  public int size() {
    return (rear + maxSize - front) % maxSize;
  }

  // 显示队首数据,不取出
  public int peekQueue() {
    if (isEmpty()) {
      throw new RuntimeException("队列空");
    }
    return arr[front];
  }
}

总结

主要是记住循环队列的要点,因为循环队列可以复用。

  • 因为有约定空一个元素,所以CircleArrayQueue queue = new CircleArrayQueue(4); 实际上3个元素就队满了。队满条件(rear+1)%maxSize==front
  • rear指针始终指向队尾元素后一个位置
  • front指针始终指向队首元素位置
  • 涉及数组下标的操作都要注意取模
  • 队空条件rear == front 这个看图想一下就明白了

你可能感兴趣的:(数据结构,Java基础,数据结构,java,算法,队列,数组)