队列

------------恢复内容开始------------

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 }

 

posted @ 2021-02-03 16:51  L1998  阅读(101)  评论(0)    收藏  举报