自定义java队列--先进先出(循环队列、链队列)

队列: 只允许在一端进行插入操作(队尾),在另一端进行删除操作(队头)。 队列的特征就是: 先进先出

队列的思想及实现也同样非常简单。在生活中的各种常常都需要排队进行,键盘中缓存区、操作系统中的作业调度等都有用到队列先进先出的思想。在这里同样用一个示意图展示队列的基本思想。
在这里插入图片描述
下面笔者才用数组存储元素,实现了一个循环队列

队列中最重要的一个方法就是队列是否满的判断,

判断队列是否为满。队满: rear + 2 = front 或 front + maxSize -2 = rear

判断队列是否为空。队空: rear + 1 = front 或 front + maxSize -1 = rear

	/** 判断队列是否为空。队空: rear + 1 = front 或 front + maxSize -1 = rear
	 *  通过数组容量比队列数据项的最大值大一,来区分对空和对满。
	 */	
	public boolean isEmpty(){
		return (rear + 1 == front || front + maxSize -1 == rear);  
	}
	
	 /**判断队列是否为满。 队满: rear + 2 = front 或 front + maxSize -2 = rear
	  * 通过数组容量比队列数据项的最大值大一,来区分对空和对满。
	  */
	public boolean isFull(){
		return (rear + 2 == front || front + maxSize -2 == rear);
	}

**获取队列大小(元素个数):**可以通过队头队尾计算出队列的大小,也可以通过一个计数器,当入队是加1,出队是减1.

	/** 获取队列的大小
	 */
	public int queueSize(){
		if(rear >= front){
			return rear - front +1;
		}else {
			return maxSize - front + (rear + 1);
		}
	}

出队入队查看队头元素:

入队:

在这里插入图片述

出队:
在这里插入图片描述
全部代码及测试:

package org.TT.Queue;
/**
 * 循环队列: 先进先出
 *        队列同样是个概念上的辅助工具。这里采用数组完成队列的操作,仍然采用泛型
 *        队列的数据项的入队、出队时间复杂度为常数 O(1)。
 *        通过队头队尾指针的移动保存所有数据位置不动,而不是移动数据项。
 *        在这里,数组的大小比队列存放数据元素大1,主要是为了方便队满的判断。
 */
public class Queue<T> {
 
	private int maxSize;   // 队列最多容纳数量
	private Object[] queueArray;
	private int front;   // 队头
	private int rear;	// 队尾
	private int size;
	
	public Queue(int length) {
		maxSize = length;
		queueArray = new Object[maxSize];
		front = 0;   
		rear = -1; 
		size = 0;
	}
	
	/**	入队: 先将rear(队为指针) 加1, 后将数据项存入rear的位置。
	 *	当rear 指向maxSize -1 的位置时,将rear 设置为-1(循环队列),加1 后存入数据项。
	 */
	public void enQueue(T str){
		
		if(isFull()){    // 入队之前先检查队列是否已满,已满则抛出异常。
				throw new RuntimeException("队列已满," + str + " 不能入队!");
		}
		
		if(rear == maxSize -1){
			rear = -1;
		}
		queueArray[++rear] = str;  // 先将 rear 加1,后取值
		size++;
	}
	
	
	/**出队: 先取出front 的值,然后将front 减1 
	 * 如果 front 超过了数组的顶端,将 front 设置为 0(循环队列)
	 */
	@SuppressWarnings("unchecked")
	public T deQueue(){
		
		if(isEmpty()){   // 出队之前先检查队列是否为空, 为空则抛出异常。
				throw new RuntimeException("队列为空,不能出队!");
		}
		
		T str = (T) queueArray[front++];  // 先去 queueArray[front] 的值,后将front 加1
		if(front == maxSize){
			front = 0;
		}
		size--;
		return str;
	}
	
	/**查看对头数据项
	 */
	@SuppressWarnings("unchecked")
	public T peek(){
		if(isEmpty()){   // 查看队头时,判断是否为空, 为空则抛出异常。
				throw new RuntimeException("队列为空!");
		}
		return (T) queueArray[front];
	}
 
	/** 判断队列是否为空。队空: rear + 1 = front 或 front + maxSize -1 = rear
	 *  通过数组容量比队列数据项的最大值大一,来区分对空和对满。
	 */	
	public boolean isEmpty(){
		return (rear + 1 == front || front + maxSize -1 == rear);  
	}
	
	 /**判断队列是否为满。 队满: rear + 2 = front 或 front + maxSize -2 = rear
	  * 通过数组容量比队列数据项的最大值大一,来区分对空和对满。
	  */
	public boolean isFull(){
		return (rear + 2 == front || front + maxSize -2 == rear);
	}
	
	/** 获取队列的大小
	 */
	public int queueSize(){
	/* 可以通过队头队尾计算出队列的大小,也可以通过一个计数器,当入队是加1,出队是减1.
	 if(rear >= front){
			return rear - front +1;
		}else {
			return maxSize - front + (rear + 1);
		}
	*/
		return size;
	}
	
	public static void main(String[] args) {
		Queue<String> queue = new Queue<>(5);
		queue.enQueue("a");
		queue.enQueue("b");
		queue.enQueue("c");
		queue.enQueue("d");
		queue.deQueue();
		queue.deQueue();
		
		System.out.println("队列是否为空: " + queue.isEmpty() + "  队列是否满: " + queue.isFull());
		System.out.println("队列大小:" + queue.queueSize());
		
		int size = queue.queueSize();
		for(int i = 0; i < size; i++){
			String str = queue.deQueue();
			System.out.print(str + " ");
		}
		
	}
	
}

结果:
在这里插入图片描述
关于链队列只是在单链表的基础上多了简单的修改,在单链表中添加一个尾指针即可,每次入队、出队只分别对单链表的队尾和队首进行插入和删除在操作,由于链队没有队满的限制,所以相对于非常简单,而判空操作只需判断 front == rear 是否成立。 在这里笔者就不列出链队列。在java库中也有队列相关的接口及实现并且还有双端队列、优先队列等类。

转载:https://blog.csdn.net/tanjiquan/article/details/50677141

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值