传统数组实现的队列有缺陷,当多次入队出队后,队头指针会后移,当队尾指针达到数组末尾时,会提示队列已满,导致数组前部分空间被浪费。如果当队尾和队头指针到达数组末尾时能从数组[0]继续添加数据,可以提升数组空间利用率。
循环数组也包含队头,队尾指针。每次入队/出队 都利用+1取模的方法(加一后如果大于数组长度,则会从0开始计算),让队头、队尾指针不会超出数组长度,实现循环的效果。
(head+1)%arr.length
代码如下(源自LeetCode):
1 package ABAB; 2 3 class MyCircularQueue { 4 5 private int[] data; //储存元素的数组 6 private int head; //队头指针 7 private int tail; //队尾指针 8 private int size; //队列容量 9 10 /** 11 * 初始化队列,队头、队尾置位-1 12 */ 13 /** Initialize your data structure here. Set the size of the queue to be k. */ 14 public MyCircularQueue(int k) { 15 data = new int[k]; 16 head = -1; 17 tail = -1; 18 size = k; 19 } 20 21 /** 22 * 入队,队尾+1,并且保存数据。如果此时为空队列,队头也要置位0,因为只有一个元素时,他既是队头,又是队尾。 23 */ 24 /** Insert an element into the circular queue. Return true if the operation is successful. */ 25 public boolean enQueue(int value) { 26 if (isFull() == true) { 27 return false; 28 } 29 if (isEmpty() == true) { 30 head = 0; 31 } 32 tail = (tail + 1) % size; 33 data[tail] = value; 34 return true; 35 } 36 37 /** 38 * 出队,增加了队列是否为空的判断,如果队头==队尾(队列为空),则将这两个指针置为-1,若不为空则队头+1 39 */ 40 /** Delete an element from the circular queue. Return true if the operation is successful. */ 41 public boolean deQueue() { 42 if (isEmpty() == true) { 43 return false; 44 } 45 if (head == tail) { 46 head = -1; 47 tail = -1; 48 return true; 49 } 50 head = (head + 1) % size; 51 return true; 52 } 53 54 /** Get the front item from the queue. */ 55 public int Front() { 56 if (isEmpty() == true) { 57 return -1; 58 } 59 return data[head]; 60 } 61 62 /** Get the last item from the queue. */ 63 public int Rear() { 64 if (isEmpty() == true) { 65 return -1; 66 } 67 return data[tail]; 68 } 69 70 /** 71 * 判断是否为空使用的是判断head是否为-1。在已经有元素入队以后,head不会等于-1。在出队操作时,如果队列已为空(head==tail),会将head置为-1,此时调用isEmpty为true. 72 */ 73 /** Checks whether the circular queue is empty or not. */ 74 public boolean isEmpty() { 75 return head == -1; 76 } 77 78 /** 79 * 判断是否为满,如果((tail + 1) % size) == head,说明队尾已经循环了一圈,到达队头的前面了,此时队列为满。 80 */ 81 /** Checks whether the circular queue is full or not. */ 82 public boolean isFull() { 83 return ((tail + 1) % size) == head; 84 } 85 }