Java基础 - 循环队列及实现

循环队列:
为了重新利用顺序队列底层数组中删除所有元素所占用的空间,消除可能出现的“假满”现象,可以将顺序队列改进为循环队列。

循环队列是一种收尾相连的队列:当front、rear变量值达到底层数组的capacity - 1之后,在前进一位就自动变成 0 。如下图所示示意图:


对于循环队列,不管队列是空还是满,都会出现一种情况:front == rear。如果底层数组中elementData[front] == null;则表明此时队列为空,否则表明该队列已满。


下面是代码实现:

import java.util.Arrays;

public class LoopQueue <T> {
	//默认队列容量为10
	private final int DEFAULT_CAPACITY = 10;
	//底层数组
	private Object[] elementData;
	//容量
	private int capacity;
	//
	private int front = 0;
	private int  rear = 0;

	public LoopQueue(){
		this.capacity = DEFAULT_CAPACITY;
		elementData = new  Object[capacity];
	}
	public LoopQueue(T element){
		this();
		elementData[0] = element;
		rear ++;
	}
	public LoopQueue(T element, int initCapacity){
		this.capacity = initCapacity;
		elementData = new  Object[capacity];
		elementData[0] = element;
		rear ++;
	}

	//队列长度
	public int length(){
		if(isEmpty()){
			return 0;
		}
		return (rear > front) ? rear - front : capacity - (front - rear);
	}
	//判是否为空
	public boolean isEmpty(){
		return rear == front && elementData[front] == null;
	}
	//向队列rear端插入元素
	public void add(T element){
		indexOutOfBoundsForAdd(rear);
		elementData[rear ++] = element;
		rear = (rear == capacity ? 0 : rear);
	}
	//向队列front端删除并返回 该元素
	@SuppressWarnings("unchecked")
	public T remove(){
		noneElementForRemove();

		T t = (T) elementData[front];
		elementData[front ++] = null;
		front = (front == capacity ? 0 : front);
		return t;
	}
	//element()返回但不删除front端元素
	@SuppressWarnings("unchecked")
	public T element(){
		noneElementForRemove();

		return (T) elementData[front];
	}
	//清空队列
	public void clear(){
		Arrays.fill(elementData, null);
		front = 0;
		rear = 0;
	}
	//toString 方法
	public String toString(){
		if(isEmpty()){
			return "[]";
		}
		else{
			StringBuilder sb = new StringBuilder("[");
			if(rear > front){
				for(int i = front; i < rear; i ++){
					sb.append(elementData[i].toString() + ",");
				}
			}else{
				/*for(int i = front; i < capacity; i ++){
					sb.append(elementData[i].toString() + ",");
				}
				for(int j = 0; j < rear; j ++){
					sb.append(elementData[j].toString() + ",");
				}*/
				//或者下面这种
				for(int i = front; i < capacity + rear; i ++){
					sb.append(elementData[i % capacity].toString() + ",");
				}
			}
			return sb.toString().substring(0, sb.length() - 1) + "]";
		}
	}


	private void indexOutOfBoundsForAdd(int index){
		if(index == front && elementData[front] != null){
			throw new IndexOutOfBoundsException("exception for LoopQueue is filled:index of add is " + index);
		}
	}
	private void noneElementForRemove(){
		if(isEmpty()){
			throw new IndexOutOfBoundsException("none any element in SequenceQueue to remove!");
		}
	}
}
测试代码跟前面的一样:
import com.yc.list.LoopQueue;

public class LoopQueueTest {
	public static void main(String[] args) {
		 LoopQueue<String> queue = new LoopQueue<String>("aaa", 4);
		 queue.add("bbb");
		 queue.add("ccc");
		 queue.add("ddd");
		 System.out.println( "队列为:    " + queue);
		 System.out.println();
		 
		 String sElement = queue.element();
		 System.out.println( "队列为:    " + queue);
		 System.out.println( "队首为:    " + sElement);
		 System.out.println();
		 
		 String sRemove = queue.remove();
		 System.out.println( "队列为:    " + queue);
		 System.out.println( "移除的队首为:    " + sRemove);
		 System.out.println();
		 
		 queue.add("eee");
		 System.out.println( "队列为:    " + queue);
		 
	}
}

测试结果为:


上面的程序创造了一个底层数组长度为4的循环队列,因此向队列中添加4个元素后队列处于“满”状态,此时再向队列添加元素将发生异常。当调用队列的

remove()方法后将front端的元素从队列删除,多出来的空间可以循环使用,可以再次添加新的数据元素 “eee”。并不会抛出异常。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值