public class deque {
	int maxSize; // 表示队列的最大容量
	int front; // 表示队列的头部也就是队列的第一个元素
	int rear; // 表示队列的尾部即队列的最后一个数字
	int[] deque; // 用来充当队列的容器

	public deque() {
	} // 空参构造
		// 带参构造用来创建指定容量的队列容器

	public deque(int maxSize) {
		// 此处加1是为了区分队列满和队列为空,
		// 如果队列没有多余空间,队列满和队列为空指针所在的位置是相同的无法区分
		// 增加一个空余的空间后,默认当整个数组还剩一个位置的时候为队列满,这样就可以和空队列区分开来
		this.maxSize = maxSize + 1;
		this.front = 0;
		this.rear = -1;
		this.deque = new int[this.maxSize];
	}

	// 判断队列是否已经满了
	private boolean isFull() {
//		// 这个地方的判断要分两种情况:尾部指针大于头部指针,以及尾部指针小于头部指针
//		// 根据不同的情况进行判断
//		if(rear > front) { 
//			// 如果尾部指针大于头部指针,
//			// 在这种情况下,头部指针在下标为0的位置,尾部指针在maxSize-2的位置
//			// (maxSize-1代表数组的顶端,应为实现约定还剩一个空位置的时候队列就代表满了,所以此时尾部指针的下标为maxSize-2)
//			if(front + (maxSize - 2) == rear) 
//				return true;
//			else 
//				return false;
//		}else{ 
//			// 如果尾部指针小于头部指针
//			// 在这种情况下,如果队列为满那面那面之间的下标相差为2
//			if(front + 2 == rear) 
//				return true;
//			else
//				return false;
//		}
		// 上面的代码只是为了方便讲解实际实现只需要一行代码
		return (front + 2 == rear || front + (maxSize - 2) == rear);
	}

	// 判断队列是否是空的
	public boolean isEmpty() {
		// 判断队列是否为空和队列是否满了思路是一样的
		// 如果没有约定只一个位置代表队列满,两者的判断条件是一模一样的
		return (front + 1 == rear || front + (maxSize - 1) == rear);
	}

	// 定义入队列方法
	public void push(int number) {
		// 判断队列是否已经满了
		if (isFull()) { // 满了的话提示用户然后跳出方法
			System.out.println("不能在添加了,已经满了");
			return;
		}
		// 先处理尾部指针,判断尾部指针是否在队列的顶端
		if (rear == maxSize - 1) {
			rear = -1; // 如果尾部指针已经在队列的顶端那么让指针回到-1
		}
		deque[++rear] = number; // 注意此处的++一定要放在rear之前(++放在变量之前变量先自增在运算,++放在变量之后先运算然后才会自增)
	}

	// 定义出队列方法
	public void remove() {
		// 先判断队列是否为空
		if (isEmpty()) {
			System.out.println("队列已经空了,没的删了");
		}
		// 出队列头部指针后移一位,要判断指针的位置是不是在队列的顶端,如果是要做处理
		int temp = deque[front++]; // 此时的temp = deque[front]这个临时变量用来提示删除的数据
		if (front == maxSize) { // 此时的font已经自增过一次所以直接和maxSize进行比较
			front = 0;
		}
		System.out.println(deque[front - 1]); // 返回删除的数据
	}

	// 跟读索引查看队列的数据
	public void peek(int index) {
		System.out.println(deque[index]);
	}
}