一,数组模拟队列
规定头指针front和尾指针rear都为-1,front=-1表示头指针指向队头的前一个位置,尾指针rear=-1表示指向队尾,这两句话要好好的理解,
maxSize为队列的大小
arr[ ]使用来存储数据的数组,大小由maxSize来定,
判断队列是否为空:当队尾和队头合并则代表队列为空,rear == front
判断队列是否已满:当队尾的索引等于队列长度-1,因为索引从0开始,所以队列的长度要-1才和队尾索引相等,rear == maxSize-1
入队:先判断是否已满,不满的话尾指针后移一个位置(rear++),然后将元素放入数组
出队:判断队列是否为空,不为空的话头指针后移(front++)
代码:
1 package Queue; 2 3 import java.util.Scanner; 4 5 public class ArrayQueue { 6 7 public static void main(String[] args) { 8 ArrayQueue arrayQueue = new ArrayQueue(6); 9 Scanner scanner = new Scanner(System.in); 10 char key = ' '; 11 boolean loop = true; 12 while (loop) { 13 System.out.println("a 入队"); 14 System.out.println("r 出队"); 15 System.out.println("g 遍历队列"); 16 System.out.println("h 查看队头元素"); 17 key = scanner.next().charAt(0);//接收一个字符串 18 switch (key) { 19 case 'a': 20 System.out.println("输入一个数"); 21 int value = scanner.nextInt(); 22 arrayQueue.addQueue(value); 23 break; 24 case 'r': 25 try { 26 int removeNum = arrayQueue.removeQueue(); 27 System.out.println("取出的数据为:" + removeNum); 28 } catch (Exception e) { 29 System.out.println(e.getMessage()); 30 } 31 break; 32 case 'g': 33 try { 34 arrayQueue.getAllQueue(); 35 } catch (Exception e) { 36 System.out.println(e.getMessage()); 37 } 38 break; 39 case 'h': 40 try { 41 int headNum = arrayQueue.headQueue(); 42 System.out.println("队头为:"+headNum); 43 }catch (Exception e){ 44 System.out.println(e.getMessage()); 45 } 46 } 47 } 48 } 49 50 int maxSize; 51 int rear; 52 int front; 53 int arr[]; 54 55 public ArrayQueue(int arrMaxSize){ 56 maxSize = arrMaxSize; 57 rear = -1; 58 front = -1; 59 arr = new int[maxSize]; 60 } 61 62 //判断队列是否为空 63 public boolean isEmpty(){ 64 return rear == front; 65 } 66 67 //判断队列是否已满 68 public boolean isFull(){ 69 return rear == maxSize-1; 70 } 71 72 //入队 73 public void addQueue(int num){ 74 if (isFull()){ 75 System.out.println("队列满的"); 76 return; 77 } 78 rear++; 79 arr[rear] = num;//入队 80 } 81 82 //出队(单个元素) 83 public int removeQueue(){ 84 if (isEmpty()){ 85 throw new RuntimeException("队列没有元素"); 86 } 87 front++; 88 return arr[front]; 89 } 90 91 //遍历队列所有元素 92 public void getAllQueue(){ 93 if (isEmpty()){ 94 throw new RuntimeException("队列为空"); 95 } 96 for (int i = 0 ; i <= arr.length ; i++){ 97 System.out.println("队列元素下标:"+i+" "+"队列元素值:"+arr[i]); 98 } 99 } 100 101 //查看队头元素 102 public int headQueue(){ 103 if (isEmpty()){ 104 throw new RuntimeException("队列为空"); 105 } 106 return arr[front+1]; 107 } 108 }
但是上述代码存在一个问题,数组使用过一次就不能使用了(因为头指针front和尾指针rear都指向了入队口,虽然里面还有很多空间,但是不能用,是一个“假的”满队列),如果要复用,则应该改造成环形队列
二:环形队列
思路:对front变量的含义做调整,front指向队列第一个元素,初始值为0,rear指向最后一个元素的前一个元素,留出一个空位作为约定,rear初始值为0
判断队满:(rear+1)%maxSize == front;
上图:rear=4,front=0,maxSize=5
(4+1)%5=0
判断队空:rear == front
rear和front初始化都为0,如果rear==front,为空
队列中元素个数:(rear+maxSize-front)%maxSize
如上队满图:(4+5-0)%5 = 4
代码:
1 package Queue; 2 3 import java.util.Scanner; 4 5 public class CircleArrayQueue { 6 public static void main(String[] args) { 7 CircleArray arrayQueue = new CircleArray(4); 8 Scanner scanner = new Scanner(System.in); 9 char key = ' '; 10 boolean loop = true; 11 while (loop) { 12 System.out.println("a 入队"); 13 System.out.println("r 出队"); 14 System.out.println("g 遍历队列"); 15 System.out.println("h 查看队头元素"); 16 key = scanner.next().charAt(0);//接收一个字符串 17 switch (key) { 18 case 'a': 19 System.out.println("输入一个数"); 20 int value = scanner.nextInt(); 21 arrayQueue.addQueue(value); 22 break; 23 case 'r': 24 try { 25 int removeNum = arrayQueue.removeQueue(); 26 System.out.println("取出的数据为:" + removeNum); 27 } catch (Exception e) { 28 System.out.println(e.getMessage()); 29 } 30 break; 31 case 'g': 32 try { 33 arrayQueue.getAllQueue(); 34 } catch (Exception e) { 35 System.out.println(e.getMessage()); 36 } 37 break; 38 case 'h': 39 try { 40 int headNum = arrayQueue.headQueue(); 41 System.out.println("队头为:"+headNum); 42 }catch (Exception e){ 43 System.out.println(e.getMessage()); 44 } 45 } 46 } 47 } 48 49 } 50 class CircleArray{ 51 int maxSize; 52 int rear; 53 int front; 54 int arr[]; 55 56 public CircleArray(int arrMaxSize){ 57 maxSize = arrMaxSize; 58 arr = new int[maxSize]; 59 front = 0; 60 rear = 0; 61 } 62 //判断队列是否为空 63 public boolean isEmpty(){ 64 return rear == front; 65 } 66 //队列是否已满 67 public boolean isFull(){ 68 return (rear+1)%maxSize == front; 69 } 70 71 //入队 72 public void addQueue(int num){ 73 if (isFull()){ 74 System.out.println("队列满的"); 75 return; 76 } 77 arr[rear] = num;//入队 78 rear = (rear+1)%maxSize; 79 } 80 //出队(单个元素) 81 public int removeQueue(){ 82 if (isEmpty()){ 83 throw new RuntimeException("队列没有元素"); 84 } 85 int value = arr[front]; 86 front = (front + 1) % maxSize; 87 return value; 88 } 89 90 //元素有效个数 91 public int size(){ 92 return (rear+maxSize-front)%maxSize; 93 } 94 95 //遍历队列所有元素 96 public void getAllQueue(){ 97 if (isEmpty()){ 98 throw new RuntimeException("队列为空"); 99 } 100 //从front开始遍历 101 for (int i = front ; i <= size() ; i++){ 102 System.out.printf("arr[%d]=%d ",i % maxSize,arr[i % maxSize]); 103 } 104 } 105 106 //查看队头元素 107 public int headQueue(){ 108 if (isEmpty()){ 109 throw new RuntimeException("队列为空"); 110 } 111 return arr[front]; 112 } 113 114 }
环形队列还不是很清楚