package com.tomdd.v2.queue;
/**
*
* <pre>
* <h1>基于数组实现环形队列</h1>
* 在Java中,基于数组实现环形队列是一种常见的数据结构实现方式,
* 它利用固定长度的数组模拟循环队列的行为,
* 以克服普通数组实现队列时可能出现的空间浪费问题。
* 下面是一个完整的Java类实现,
* 包括必要的属性、构造方法、入队(enqueue)、出队(dequeue)、
* 判断队列是否为空或满、获取队列大小等核心方法
*
*<h2>重点:</h2>
* 使用取模算法,移动指针,实现环形队列的逻辑
*<h2>思路分析:</h2>
* (1)构造方法:根据给定的capacity创建一个指定大小的数组,并初始化front和rear指针为0<br/>
* (2)isEmpty:检查front和rear是否相等,相等表示队列为空。<br/>
* (3) isFull:计算(rear + 1) % capacity是否等于front。如果相等,<br/>
* 说明队尾元素的下一个位置就是队首,即队列已满。(环形队列预留一个位置)<br/>
* (4)size:由于是环形队列,front和rear可能会因为队列元素的进出而形成“跨越”,<br/>
* 即rear小于front。此时,队列的实际大小需要加上数组的剩余空间(rear + capacity - front)。<br/>
* 如果不跨越,则直接计算rear - front<br/>
* (5)enqueue:在队尾插入元素。首先检查队列是否已满,未满则将元素放入queue[rear]位置,<br/>
* 并更新rear指针(取模确保它始终在数组范围内循环移动)rear = (rear + 1) % capacity;。<br/>
* (6)dequeue:从队首移除并返回元素。同样先检查队列是否为空,<br/>
* 非空则取出queue[front]作为结果,将其设为null(可选,有助于垃圾回收),<br/>
* 然后更新front指针:front = (front + 1) % capacity。<br/>
* (7) 查看队尾元素: queue[(rear - 1 + capacity) % capacity] <br/>
* (8) 查看头元素: queue[front]
* </pre>
*
* @param <T>
*/
public class CircularArrayQueue<T> {
// 定义队列内部存储数组以及其最大容量
private final T[] queue;
private final int capacity;
// 队首指针(指向队列的第一个有效元素)
private int front;
// 队尾指针(指向队列最后一个有效元素的下一个位置)环形队列预留一个位置
private int rear;
/**
* 构造方法,初始化指定容量的环形队列
*
* @param capacity 队列容量
*/
@SuppressWarnings("unchecked")
public CircularArrayQueue(int capacity) {
this.capacity = capacity + 1;
this.queue = (T[]) new Object[capacity];
this.front = 0;
this.rear = 0;
}
/**
* 判断队列是否为空
*
* @return true - 为空,false - 不为空
*/
public boolean isEmpty() {
return front == rear;
}
/**
* 判断队列是否已满
*
* @return true - 已满,false - 未满
*/
public boolean isFull() {
return (rear + 1) % capacity == front;
}
/**
* 获取队列当前实际元素数量
*
* @return 队列大小
*/
public int size() {
if (rear < front) {
return rear + capacity - front;
} else {
return rear - front;
}
}
/**
* 入队操作,将元素添加到队尾
*
* @param item 待入队元素
* @return true - 入队成功,false - 队列已满无法入队
*/
public boolean enqueue(T item) {
if (!isFull()) {
queue[rear] = item;
rear = (rear + 1) % capacity;
return true;
}
return false;
}
/**
* 出队操作,移除并返回队首元素
*
* @return 出队元素,若队列为空则返回 null
*/
public T dequeue() {
if (!isEmpty()) {
T result = queue[front];
// 释放队首元素的引用(可选,避免对象游离)
queue[front] = null;
front = (front + 1) % capacity;
return result;
}
return null;
}
/**
* 打印队列所有元素
*/
public void printQueue() {
if (isEmpty()) {
System.out.println("Queue is Empty!");
return;
}
int tempFront = front;
while (tempFront != rear) {
System.out.print(queue[tempFront] + " ");
tempFront = (tempFront + 1) % capacity;
}
System.out.println();
}
/**
* 查看队尾元素
*
* @return 队尾元素
*/
public T peekRear() {
if (isEmpty()) {
throw new IllegalArgumentException("Queue is Empty!");
}
return queue[(rear - 1 + capacity) % capacity];
}
/**
* 查看头元素
*
* @return 查看头元素
*/
public T peekFront() {
if (isEmpty()) {
throw new IllegalArgumentException("Queue is Empty!");
}
return queue[front];
}
public static void main(String[] args) {
CircularArrayQueue<Integer> circularQueue = new CircularArrayQueue<>(5);
circularQueue.enqueue(1);
circularQueue.enqueue(2);
circularQueue.enqueue(3);
circularQueue.enqueue(4);
circularQueue.enqueue(5);
circularQueue.printQueue();
System.out.println("-------------------------");
Integer i = circularQueue.peekRear();
System.out.println("队尾元素:" + i);
Integer i1 = circularQueue.peekFront();
System.out.println("头元素:"+i1);
circularQueue.printQueue();
System.out.println("-------------------------");
System.out.println(circularQueue.dequeue()); // 输出:1
System.out.println(circularQueue.size()); // 输出:2
}
}
基于数组实现环形队列
最新推荐文章于 2024-06-21 17:14:47 发布