队列是一个有序列表,可以用数组或是链表来实现,遵循先入先出的原则,这是队列的特点。我们要实现的是循环队列。什么是循环队列呢?环形队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间。
举个例子,我们定义一个长度为4的队列,1,2,3,4依次入队,那么现在队列中的情况是[1,2,3,4],如果我们想下一个数5入队,显然是不行的,因为队列满了,我们需要队列中有数字离开,根据先进先出原则,1必须得离开,1离开后的队列为[X,2,3,4],这时候5入队,5是最后一个入队的,但是它的位置却是原来1在的地方,也就[5,2,3,4],存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间也就是这么个意思,不知道大家理解没有?反正我是懂了。。。
队列的属性定义:
1 // 表示队列的长度 2 private int maxQueueSize; 3 // head表示队列的头指向,初始值 = 0 4 private int head; 5 // head表示队列的尾指向,初始值 = 0 6 private int tail; 7 // 该数组用于存放真实的数据 8 private int[] dataArr;
四个属性,都有用,别少了哦。
队列的带参构造方法,用于创建队列,传入的参数为队列长度-1:
1 public CircleQueue(int queueSize) { 2 maxQueueSize = queueSize + 1; 3 dataArr = new int[maxQueueSize]; 4 }
接下来是一些通用方法的实现:
1 // 判断队列是否为空 2 public boolean isEmpty() { 3 return tail == head; 4 } 5 // 判断队列是否已满 6 public boolean isFull() { 7 return (tail + 1) % maxQueueSize == head; 8 }
说明:在循环队列中,当队列为空时,有tail = head ,而当所有队列全占满时,也有tail = head。为了区别这两种情况,我们定义的循环队列最多只能有maxQueueSize -1个元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是tail = head,而队列判满的条件是head=(tail + 1) % maxQueueSize。
入队:只在队列的尾(tail)进行添加操作
1 public void addData(int n) { 2 if (isFull()) { 3 System.out.println("队已列满,不能加入数据!"); 4 return; 5 } 6 7 dataArr[tail] = n; 8 tail = (tail + 1) % maxQueueSize; 9 System.out.println(tail); 10 }
出队:只在队列的头(head)进行删除操作:
1 public int getData() { 2 if (isEmpty()) { 3 throw new RuntimeException("队列为空,不能取数据"); 4 } 5 // 先把 head 对应的值保留到一个临时变量 6 int value = dataArr[head]; 7 // 将 head 后移, 取模 8 head = (head + 1) % maxQueueSize; 9 // 将临时保存的变量返回 10 return value; 11 }
此文章转载自一马关月的队列,地址为:https://www.cnblogs.com/maguanyue/p/11529983.html