- 队列是一个有序列表,可以用【数组】或【链表】来实现
- 遵循先入先出的原则。即:先存入队列的数据,要先取出;后存入的要后取出。
数组模拟队列
思路分析
示意图
队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如上图, 其中 maxSize 是该队列的最大容量。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变。
当我们将数据存入队列时称为 addQueue,需要两个步骤:
- 将尾指针往后移:rear+1 , 当front == rear 时,【队列空】
- 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。 rear == maxSize - 1 时,【队列满】
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| public class ArrayQueue {
private int maxSize; private int front; private int rear; private int[] arr; private int length ;
public ArrayQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; front = -1; rear = -1; length = 0 ; }
public boolean isFull() { return rear == maxSize - 1; }
public boolean isEmpty() { return rear == front; }
public void addQueue(int n) { if (isFull()) { System.out.println("队列已满,不能加入数据~"); return; } rear++; arr[rear] = n; length++; }
public int getQueue() { if (isEmpty()) { throw new RuntimeException("队列为空,不能取数据"); } front++; length--; return arr[front];
}
public void showQueue() { if (isEmpty()) { System.out.println("队列空的,没有数据~~"); return; } for (int i = 0; i < arr.length; i++) { System.out.printf("arr[%d]=%d\n", i, arr[i]); } }
public int headQueue() { if (isEmpty()) { throw new RuntimeException("队列为空,没有数据~~"); } return arr[front + 1]; }
public int queueLength(){ return length; } }
|
缺点分析:目前的队列只能使用一次就不能用了,没有达到复用的效果。
环形队列
对前面的数组模拟队列的优化,充分利用数组。因此将数组看做是一个环形的。(通过取模的方式来实现即可)。
思路分析
分析说明
- 尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定。这个在做判断队列满的时候需要注意: (rear + 1) % maxSize == front时,队列满。
- rear == front时, 【队列空】。
分析示意图:
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| public class CircleArrayQueue {
private int maxSize; private int front; private int rear; private int[] arr;
/ public CircleArrayQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; }
public boolean isFull() { return (rear + 1) % maxSize == front; }
public boolean isEmpty() { return rear == front; }
public void addQueue(int n) { if (isFull()) { System.out.println("队列满,不能加入数据~"); return; } arr[rear] = n; rear = (rear + 1) % maxSize; }
public int getQueue() { if (isEmpty()) { throw new RuntimeException("队列空,不能取数据"); } int value = arr[front]; front = (front + 1) % maxSize; return value; }
public void showQueue() { if (isEmpty()) { System.out.println("队列空的,没有数据~~"); return; } for (int i = front; i < front + size(); i++) { System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]); } }
public int size() { return (rear + maxSize - front) % maxSize; }
public int headQueue() { if (isEmpty()) { throw new RuntimeException("队列空的,没有数据~~"); } return arr[front]; } }
|