数组实现循环队列

今天看了一个关于用数组实现循环队列的视频,视频中的数组总有一个元素是不被使用的,试着优化了一下。
视频中认为front与rear相等时就为空,我对此做了改进。
假设队列最大容量3个元素,当入队一个元素后,front=0,rear=1,入队第三个元素后,front=0,rear=0
在这里插入图片描述
front和rear都在做顺时针运动,如果front追上了rear发生重合,那就为空,如果是rear追上front队列就满了。

package rx;

/**
 * @ClassName: ArrayQueueDemo   
 * @Description: 循环队列测试
 * @author: rx
 * @date: 2021年9月21日 下午5:29:39
 */
public class ArrayQueueDemo {

	public static void main(String[] args) {
		ArrayQueue q = new ArrayQueue(3);
		q.add(1);
		q.add(2);
		q.add(3);
		q.out();
		q.add(4);
		q.out();
		q.out();
		q.add(5);
		q.add(6);
		q.show();
		System.err.println(q.size());
	}
}

/**
 * 
 * @ClassName: ArrayQueue   
 * @Description: 循环队列 数组使用率100%
 * @author: rx
 * @date: 2021年9月21日 下午5:39:03
 */
class ArrayQueue{
	
	private int front; //队首的索引 
	private int rear;  //将要入队的元素索引
	private int maxSize; //队列的最大长度
	private boolean isEmpty; //队列是否为空
	private int[] attr;
	public ArrayQueue(int maxSize) {
		this.front = 0;
		this.rear = 0;
		this.isEmpty = true; //初始队列为空
		this.attr = new int[maxSize]; 
		this.maxSize = maxSize;
	}
	
	/**
	 * 
	 * @Title: add   
	 * @Description: 入队方法
	 * @param: @param n      
	 * @return: void      
	 * @throws
	 */
	public void add(int n) {
		// 队列满了不可以入队
		if(isFull()) {
			throw new RuntimeException("队列满了,不可入队");
		}
		// 队列不再为空
		this.isEmpty = false;
		
		attr[rear] = n;
//		rear = (rear+1)%(maxSize+1) == maxSize ? 0 : (rear+1)%(maxSize+1); 之前的想法多余了
		rear = (rear+1)%maxSize;
	}
	
	/**
	 * 
	 * @Title: out   
	 * @Description: 出列方法
	 * @param: @return      
	 * @return: int      
	 * @throws
	 */
	public int out() {
		
		if(this.isEmpty) {
			throw new RuntimeException("队列为空,不可出列");
		}
		
		int value = attr[this.front];
		this.front = (front+1)%maxSize;
				
		if(this.front==this.rear) {
			this.isEmpty=true;
		}
		return value;
	}
	
	/**
	 * 
	 * @Title: isFull   
	 * @Description: 判断队列是否满了
	 * @param: @return      
	 * @return: boolean      
	 * @throws
	 */
	public boolean isFull() {
		//如果队列状态非空并且front等于rear则满了
		if(this.isEmpty == false && this.front == this.rear) {
			return true;
		}else {
			return false;
		}
	}
	
	public void show() {
		if(this.isEmpty) {
			throw new RuntimeException("队列为空");
		}
		
		//从队首遍历到队尾
		for(int i = front;i<front+this.size();i++) {
			System.out.println(attr[i%maxSize]);
		}
	}
	
	/**
	 *
	 * @Title: size   
	 * @Description:  获取队列的有效长度
	 * @param: @return      
	 * @return: int      
	 * @throws
	 */
	public int size() {
		//如果队首队尾重合且队列状态非空则为满了
		if(this.front == this.rear) {
			if(this.isEmpty == false) {
				return maxSize;
			}else {
				return 0;
			}
		}else {
			return Math.abs(front-rear);
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ranx3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值