队列
------------恢复内容开始------------
1.队列介绍
队列是一个有序列表,可以用数组或链表来实现;
遵循先入先出的原则:先存入队列的数据先取出,后存入的后取出

2.数组模拟队列

1 package ShuZuMoNiDuiLie; 2 3 import java.util.Scanner; 4 5 /* 6 * 用数组模拟队列 7 */ 8 9 public class ArrayQueueDemo { 10 public static void main(String[] args){ 11 12 //创建一个队列 13 ArrayQueue arrayQueue=new ArrayQueue(3); 14 char key=' '; 15 Scanner scanner=new Scanner(System.in); 16 17 boolean loop=true; 18 while(loop){ 19 System.out.println("s(show):显示队列"); 20 System.out.println("e(exit):退出程序"); 21 System.out.println("a(add):添加数据到队列"); 22 System.out.println("g(get):从队列取出数据"); 23 System.out.println("h(head):查看队列头的数据"); 24 key=scanner.next().charAt(0);//接收一个字符 25 26 switch(key){ 27 case's': 28 arrayQueue.showQueue(); 29 break; 30 case'a': 31 System.out.println("输入一个数"); 32 int value=scanner.nextInt(); 33 arrayQueue.addQueue(value); 34 break; 35 case'g': 36 try{ 37 int res=arrayQueue.getQueue(); 38 System.out.println("取出的数据是:"+res); 39 }catch(Exception e){ 40 System.out.println(e.getMessage()); 41 } 42 break; 43 case'h': 44 try{ 45 int res=arrayQueue.headQueue(); 46 System.out.println("队列头数据是:"+res); 47 }catch(Exception e){ 48 System.out.println(e.getMessage()); 49 } 50 break; 51 case'e': 52 scanner.close(); 53 loop=false; 54 System.out.println("程序退出!!!"); 55 break; 56 } 57 58 } 59 } 60 61 } 62 /* 63 * 这种写法存在一个问题:数组使用一次就不能再用来,因为尾部指针和头指针只能向一边移动,移到底后,两者相等,造成队列判断为空,且无法再移动指针 64 * 65 */ 66 //使用数组模拟编写一个ArrayQueue类 67 class ArrayQueue{ 68 private int maxSize;//数组最大容量 69 private int front;//队列头 70 private int rear;//队列尾 71 private int[] arr; 72 73 74 public int getFront() { 75 return front; 76 } 77 78 public void setFront(int front) { 79 this.front = front; 80 } 81 82 public ArrayQueue(int maxSize){ 83 this.maxSize=maxSize; 84 arr=new int[maxSize]; 85 front=-1;//指向队列头部,指向队列头的前一个位置 86 rear=-1;//指向队列尾部,指向队列尾的数据 87 } 88 89 //判断队列是否满 90 public boolean isFull(){ 91 return rear==maxSize-1; 92 } 93 94 95 //判断队列是否空 96 public boolean isEmpty(){ 97 return rear==front; 98 } 99 100 //添加数据到队列 101 public void addQueue(int n){ 102 if(isFull()){ 103 System.out.println("队列已满"); 104 }else{ 105 rear++; 106 arr[rear]=n; 107 } 108 } 109 110 //获取队列数据:数据出队列 111 public int getQueue(){ 112 if(isEmpty()){ 113 //若数组位空,抛出异常 114 throw new RuntimeException("队列为空!!!"); 115 }else{ 116 front++; 117 return arr[front]; 118 } 119 } 120 121 //显示队列的所有数据 122 public void showQueue(){ 123 if(isEmpty()){ 124 System.out.println("队列空,没有数据!!!"); 125 return; 126 }else{ 127 for(int i=0;i<arr.length;i++){ 128 System.out.printf("arr[%d]=%d\n",i,arr[i]); 129 } 130 } 131 } 132 133 //显示队列头数据,这个和取数据不同 134 public int headQueue(){ 135 if(isEmpty()){ 136 throw new RuntimeException("队列为空!!!"); 137 }else{ 138 139 return arr[front+1]; 140 141 } 142 } 143 }
存在问题:
这种写法存在一个问题:数组使用一次就不能再用来,因为尾部指针和头指针只能向一边移动,移到底后,两者相等,造成队列判断为空,且无法再移动指针.
改进方法:
使用环形队列
思路:在队列中空出一个位置,例如容量为3的队列,只放置2个元素,另一个位置空出来做缓冲。
(1)front变量:之前front是指向当前元素的前一个位置,这里改为指向当前元素位置
(2)real变量:之前real变量是指向当前元素位置,这里修改为指向当前元素的后一个位置
(3)队列满的条件:(real+1)%maxSize==front
(4)队列空的条件:real==front
(5)队列中有效元素个数:(real+maxSize-front)%maxSize
1 package ShuZuMoNiDuiLie; 2 3 import java.util.Scanner; 4 5 public class CircleQueueDemo { 6 public static void main(String[] args){ 7 CircleQueue c=new CircleQueue(3); 8 boolean loop=true; 9 Scanner s=new Scanner(System.in); 10 char key; 11 12 while(loop){ 13 System.out.println("s(show):显示队列"); 14 System.out.println("e(exit):退出程序"); 15 System.out.println("a(add):添加数据到队列"); 16 System.out.println("g(get):从队列取出数据"); 17 System.out.println("h(head):查看队列头的数据"); 18 System.out.println("t(tail):查看队列尾的数据"); 19 20 key=s.next().charAt(0);//接收一个字符 21 22 switch(key){ 23 24 case's': 25 c.showQueue(); 26 break; 27 case'a': 28 System.out.println("输入一个数"); 29 int value=s.nextInt(); 30 c.addQueue(value); 31 break; 32 case'g': 33 try{ 34 int res=c.getQueue(); 35 System.out.println("取出的数据是:"+res); 36 }catch(Exception e){ 37 System.out.println(e.getMessage()); 38 } 39 break; 40 case'h': 41 try{ 42 int res=c.headQueue(); 43 System.out.println("队列头数据是:"+res); 44 }catch(Exception e){ 45 System.out.println(e.getMessage()); 46 } 47 break; 48 case't': 49 try{ 50 int res=c.tailQueue(); 51 System.out.println("队列尾的数据是:"+res); 52 }catch(Exception e){ 53 System.out.println(e.getMessage()); 54 } 55 break; 56 case'e': 57 s.close(); 58 loop=false; 59 System.out.println("程序退出!!!"); 60 break; 61 } 62 63 } 64 65 } 66 } 67 68 69 class CircleQueue{ 70 private int front; 71 private int real; 72 private int maxSize; 73 private int arry[]; 74 75 public CircleQueue(int size){ 76 this.maxSize=size; 77 arry=new int[maxSize]; 78 front=0; 79 real=0; 80 } 81 82 //判断是否为空 83 public boolean isEmpty(){ 84 if(front==real){ 85 return true; 86 }else 87 return false; 88 } 89 90 91 92 //判断是否满 93 public boolean isFull(){ 94 if((real+1)%maxSize==front){ 95 return true; 96 }else 97 return false; 98 } 99 100 //加数据 101 public void addQueue(int n){ 102 if(isFull()){ 103 System.out.println("队列已满!!!"); 104 }else{ 105 arry[real]=n; 106 real=(real+1)%maxSize; 107 108 } 109 } 110 111 112 113 //取数据 114 public int getQueue(){ 115 if(isEmpty()){ 116 throw new RuntimeException("队列为空!!!"); 117 }else{ 118 int index=front; 119 front=(front+1)%maxSize; 120 return arry[index]; 121 } 122 } 123 124 125 126 127 //查看队列数据 128 public void showQueue(){ 129 if(isEmpty()){ 130 System.out.println("队列为空!!!"); 131 return; 132 }else{ 133 for(int i=front;i<front+((real+maxSize-front)%maxSize);i++){ //(real+maxSize-front)%maxSize为数组中数据个数 134 System.out.println("arry["+i%maxSize+"]="+arry[i%maxSize]); 135 136 } 137 } 138 } 139 140 141 142 //查看头数据 143 144 public int headQueue(){ 145 if(isEmpty()){ 146 throw new RuntimeException("队列为空!!!"); 147 }else{ 148 return arry[front]; 149 } 150 } 151 152 153 //查看尾数据 154 public int tailQueue(){ 155 if(isEmpty()){ 156 throw new RuntimeException("队列为空!!!"); 157 }else{ 158 if(real==0){ 159 return arry[maxSize-1]; 160 }else{ 161 return arry[real-1]; 162 } 163 } 164 } 165 166 167 168 169 }

浙公网安备 33010602011771号