数据结构-线性结构->队列
队列:
数据的存取遵循先进先出的原则。
实现思路:
因为队列是线性结构,所以队列可以使用数组或链表来实现;
头节点(front)表示队列的头数据,尾节点(rear)表示队列尾部的数据;【注:单链式的队列和环形队列中front和rear的初始值不同】
两个节点相当于队列的进出门卡,数据存储要登记front门卡,数据的取出要刷rear门卡,控制整个队列数据存取的方式,大小。
因为使用数组来实现列表,最好定义一个数组的容量来作为队列的最大存储空间。
代码的实现:
(1)实现简单的单例链式的列表(无法循环使用列表)
1 class Queue { 2 private int maxSize; //队列最大容量 3 private int front; //队列头数据下标 4 private int rear; //队列尾数据下标 5 private int[] queue; //数组储存队列数据 6 7 /** 8 * 队列的构造方法 9 */ 10 public Queue(int n) { 11 maxSize = n; 12 front = -1;//指向队列头,初始值应该在队列头的前一个位置 13 rear = -1;//指向队列尾,初始值与front一样 14 queue = new int[maxSize]; 15 } 16 17 /** 18 * 判断队列是否已满 19 */ 20 public boolean isFull() { 21 return rear == maxSize - 1; 22 } 23 24 /** 25 * 判断队列是否为空 26 */ 27 public boolean isEmpty() { 28 return front == rear; 29 } 30 31 /** 32 * 队列添加数据,添加数据需要先判断队列是否已满 33 */ 34 public void addQueue(int num) { 35 if (isFull()) { 36 System.out.println("队列已满,无法添加数据"); 37 return; 38 } 39 rear++; 40 queue[rear] = num; 41 } 42 43 /** 44 * 取出队列数据,取出数据先判断队列是否为空 45 */ 46 public int getQueue() { 47 if (isEmpty()) { 48 throw new RuntimeException("队列为空,无法取出数据!"); 49 } 50 front++; 51 return queue[front]; 52 } 53 54 /** 55 * 显示队列数据 56 */ 57 public void showQueue() { 58 if (isEmpty()) { 59 System.out.println("队列是空的"); 60 return; 61 } 62 for (int i = 0; i < queue.length; i++) { 63 System.out.printf("queue[%d] = %d\n", i, queue[i]); 64 } 65 } 66 67 /** 68 * 显示队列头数据 69 */ 70 public int showHead() { 71 if (isEmpty()) { 72 throw new RuntimeException("队列为空!"); 73 } 74 return queue[front + 1]; 75 } 76 }
(2)重新定义front与rear的初始值,实现环形列表,由于front和rear直接表示的是列表的头,尾节点,所以在定义列表是否已满以及添加数据之后的下标移动都需要使用到取模的概念,同时数组中还需要空出一个位置来定义队列存取数据的约束
1 class CQueue { 2 private int[] arr; // 声明一个数据储存模拟队列数据 3 private int maxSize; //队列的最大容量+预留约定的一个位置 4 private int front; // 初始值为0,指向队列头 5 private int rear; //初始值为0,指向队列的尾 6 7 /** 8 * 构造方法,初始化队列 9 */ 10 public CQueue(int num) { 11 maxSize = num; 12 arr = new int[maxSize]; 13 } 14 15 /** 16 * 判断队列是否为空 17 */ 18 public boolean isEmpty() { 19 return front == rear; 20 } 21 22 /** 23 * 判断队列是否已满 24 * 环形队列中,预留出来的一个空间用来约定队列,不储存数据 25 */ 26 public boolean isFull() { 27 return (rear + 1) % maxSize == front; 28 } 29 30 /** 31 * 队列添加数据方法 32 */ 33 public void addQueue(int n) { 34 if (isFull()) { 35 System.out.println("队列已满,无法添加数据!"); 36 return; 37 } 38 arr[rear] = n; 39 rear = (rear + 1) % maxSize; 40 } 41 42 /** 43 * 显示队列数据 44 */ 45 public int isSize() { 46 return (rear + maxSize - front) % maxSize; //取模保证数据在范围内,遍历时决定循环的步长 47 } 48 49 public void showQueue() { 50 if (isEmpty()) { 51 System.out.println("队列为空,没有数据!"); 52 return; 53 } 54 for (int i = front; i < front + isSize(); i++) { 55 System.out.printf("CQueue[%d] = %d\n", i % maxSize, arr[i % maxSize]); 56 } 57 } 58 59 /** 60 * 取出数据 61 */ 62 public int getQueue() { 63 if (isEmpty()) { 64 throw new RuntimeException("队列为空,没有数据!"); 65 } 66 int temp = arr[front]; 67 front = (front + 1) % maxSize; 68 return temp; 69 } 70 71 /** 72 * 显示队列头数据 73 */ 74 public void headQueue() { 75 if (isEmpty()) { 76 System.out.println("队列为空,没有数据!"); 77 return; 78 } 79 System.out.printf("队列头数据是:%d", arr[front]); 80 } 81 82 }
在环形队列中取模这一概念是关键,使用环形图来辅助理解。

浙公网安备 33010602011771号