队列

队列

基本概念

队列是一个有序列表,遵循**先进先出(First In First Out)**原则,只允许在一端(队尾)进行插入操作,在另一端(队头)进行取出操作。

实现

可以用数组来模拟队列,由于队列的插入和取出分别在头部和尾部两端进行操作,因此需要两个变量来front和rear分别记录队列的头部和尾部的下标,队列的大小为用maxsize表示。

  • front:随着数据的取出而改变,指向队列头部数据的前一个位置
  • rear:随着数据的插入而改变,指向队列最后一个元素

示意图:

在这里插入图片描述

队列的基本操作

队列初始化

利用构造函数进行队列的初始化操作,应当传入指定大小来创建一个数组

public Queue(int maxSize) {
		this.maxSize = maxSize;
		this.arr = new int[maxSize];
		this.front = -1;
		this.rear = -1;
}
判断队列是否为空

队列头部前一个位置下标为front,尾部下标为rear,当取出元素时队列的front往后移动一格,因此当front == rear时,队列为空。

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

队列的最大容量为maxsize,因此队列的最大下标为maxsize-1。所以,当队尾下标rear == maxsize-1时,队列已满。

public boolean isFull() {
		return rear == maxSize - 1;
}
数据入队
  • 先判断队列是否已满,如果满了,就不能让数据插入
  • 数据入队时,只需要移动尾部,头部保持不动。
  • 先将尾部下标往后移动:rear = rear + 1,然后将数据插入数据尾部位置。
public void enQueue(int element) {
		if (isFull()) {
			System.out.println("队列已满,不能插入!");
		} else {
			rear = rear + 1;
			arr[rear] = element;
		}
}
数据出队
  • 先判断队列是否为空,如果为空,就不能取出数据
  • 数据出队,只需要移动头部,尾部保持不动
  • 将头部下标移动到要出队的数据的位置,然后将该数据返回
public int deQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列中没有数据!!");
		} else {
			front = front + 1;
			return arr[front];
		}
}
打印队列
public void printQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列中没有数据!!");
		} else {
			for (int i = front + 1; i <= rear; i++) {

				System.out.print(arr[i] + "\t");
			}
		}
		System.out.println();
}

队列的假溢出

在这里插入图片描述

示意图中的第三个,随着入队和出队的操作,队列组件向后移动。当rear = maxsize-1时,队列已满。但此时队列中已经出队了两个,前面两个位置是空着的,但此时已然判断队列已经满了,这就是队列的假溢出。

循环队列

为了解决队列的假溢出,要对上面的队列进行优化,通过取模的方式来判断队列是否已满。对front和rear进行调整。

改进思路:

  • front:指向队列的第一个元素,初始值为 0
  • rear:初始值为0,指向队列的最后一个元素的后一个位置,空出一个位置做区分,而用于避免当rear和front指向同一个位置时,无法判断队列是空还是已满。
  • 此时,队列的最大容量为maxsize-1
  • 当rear==front时,队列为空
  • 当(rear+1)%maxsize==front时,队列已满
  • 此时,队列中的实际存储数据为:(rear+maxsize-front)%maxsize
代码实现
public class CircleQueue {
	private int maxSize;// 队列大小,实际存放数据大小maxsize-1
	private int[] arr;
	private int front;// 队头,指向第一个元素
	private int rear;// 队尾,指向最后一个元素后一个位置

	public CircleQueue(int maxSize) {
		this.maxSize = maxSize;
		this.arr = new int[maxSize];
		this.front = 0;
		this.rear = 0;
	}

	/**
	 * 判断是否为空
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		return rear == front;
	}

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

	/**
	 * 入队操作
	 */
	public void enQueue(int element) {
		if (isFull()) {
			System.out.println("队列已满,不能插入!");
		} else {
			//rear指向最后一个数据的后一个位置,
			//先在当前指向位置插入数据,再将rear向后移动
			arr[rear] = element;
			rear = (rear + 1) % maxSize;
		}
	}

	/**
	 * 元素出队
	 */
	public int deQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列中没有数据!!");
		} else {
			//front指向队头数据,应当先取出数据,再讲front向后移动。
			int element = arr[front];
			front = (front + 1) % maxSize;
			return element;
		}
	}

	/**
	 * 查看队列头元素
	 * 
	 * @return
	 */
	public int headQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列中没有数据!!");
		} else {
			return arr[front];
		}
	}

	/**
	 * 打印队列
	 */
	public void printQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列中没有数据!!");
		} else {
			for (int i = front; i < front + size(); i++) {

				System.out.print(arr[i % maxSize] + "  ");
			}
		}
		System.out.println();
	}

	/**
	 * 队列大小
	 * 
	 * @return
	 */
	public int size() {
		return (rear + maxSize - front) % maxSize;
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值