队列

队列的含义:
      1) 队列是一个有序的列表,可以用数组或是链表来实现
      2) 遵循先入先出的原则.即:先存入队列的数据,先取出,后存入的要后取出.

 

      数组模拟队列
         如图:

 

   解释:

    ①队列本身就是有序列表,若使用数组的结构来存储队列的数据,则队列声明如上图,最大容量是MaxSize.

    ②因为队列的输出和输入是分别从前后端来处理,因此需要两个变量分别来记录,front会随着数据的输出而改变,而rear则是随着数据的输入而改变

       ③相关的判断  首先添加一个数据rear+1 ,当front = rear 为空,当rear = maxSize-1时表示队列满了

     代码呈现如下:

  1 package DatabaseStructure.com.lsj.queue;
  2 
  3 import java.util.Scanner;
  4 
  5 /**
  6  * Created by IDEA
  7  * 创建人:wen
  8  * 创建日期: 2019-08-12
  9  * 创建时间: 10:29
 10  * 数组模拟队列
 11  * 存在问题:当我们将所有数据全部取出来之后,我们不能在去存入数据了,他会显示队列已满,产生这个问题的原因就是我们没有做成环形队列
 12  */
 13 public class ArrayQueueDemo {
 14 
 15     public static void main(String[] args) {
 16         //测试
 17         ArrayQueue queue = new ArrayQueue(3);
 18         char key = ' ';//接收用户输入
 19         Scanner scanner = new Scanner(System.in);
 20         boolean loop = true;
 21         while (loop){
 22             System.out.println("s(show):显示数据");
 23             System.out.println("e(exit):退出程序");
 24             System.out.println("a(add):添加数据到数列");
 25             System.out.println("g(get):从队列中取出数据");
 26             System.out.println("h(head):查看队列头的数据");
 27             key = scanner.next().charAt(0);//接收一个字符
 28             switch (key){
 29                 case 's':
 30                     queue.showQueue();
 31                     break;
 32                 case 'a':
 33                     System.out.println("输入一个数");
 34                     int val = scanner.nextInt();
 35                     queue.addQueue(val);
 36                     break;
 37                 case 'e':
 38                     scanner.close();
 39                     loop = false;
 40                     break;
 41                 case 'h':
 42                     try {
 43                         int i = queue.headQueue();
 44                         System.out.printf("取出的队列头数据是%d\n",i);
 45                     }catch (Exception e){
 46                         System.out.println(e.getMessage());
 47                     }
 48                     break;
 49                 case 'g':
 50                     try {
 51                         int i = queue.getQueue();
 52                         System.out.printf("取出的数据是%d\n",i);
 53                     }catch (Exception e){
 54                         System.out.println(e.getMessage());
 55                     }
 56                     break;
 57                 default:
 58                     System.out.println("输入有误!!!");
 59                     break;
 60             }
 61         }
 62 
 63     }
 64 }
 65 //使用数组模拟队列--编写一个ArrayQueue类
 66 class ArrayQueue{
 67     private int maxSize;//表示数组的最大容量
 68     private int front;//队列头
 69     private int rear;//队列尾
 70     private int[] arr; //该数组用于存放数据,模拟队列
 71 
 72     //创建队列的构造器
 73     public ArrayQueue(int maxSize){
 74         this.maxSize = maxSize;
 75         arr = new int[maxSize];
 76         front = -1;//指向队列头部,分析出front是指向队列头的前一个位置
 77         rear = -1;//指向队列尾,指向队列尾的数据
 78     }
 79     //判断队列是否满
 80     public boolean isFull(){
 81         return rear == maxSize-1;
 82     }
 83     //判断队列是否为空
 84     public boolean isEmpty(){
 85         return rear == front;
 86     }
 87     //添加数据到队列
 88     public void addQueue(int n){
 89         //判断队列是否满
 90         if (isFull()){
 91             System.out.println("队列满,不能加入数据~~");
 92             return;
 93         }
 94         arr[++rear] = n;
 95     }
 96     //获取队列数据,出队列
 97     public int getQueue(){
 98         //判断队列是否为空
 99         if (isEmpty()){
100             throw new RuntimeException("队列为空");
101         }
102         return arr[++front];
103     }
104     //显示队列所有数据
105     public void showQueue(){
106         //遍历
107         if (isEmpty()){
108             System.out.println("队列为空!!");
109         }
110         for (int i = 0; i < arr.length; i++) {
111             System.out.printf("arr[%d]=%d\n",i,arr[i]);
112         }
113     }
114     //显示队列的头数据,注意不是取出数据
115     public int headQueue(){
116         //判断为空
117         if (isEmpty()){
118             System.out.println("队列空没有数据");
119         }
120         return arr[front+1];
121     }
122 }

  发现问题: 没有达到复用

  解决方法: 使用环形的队列

  数组实现环形队列(这里存在很多种方法,我主要取的相对比较好理解的方法)

  实现思路:

    ①将front和rear指向链表的第一个节点(front = rear = 0)

    ②相关的条件:满的条件: (rear+1)%maxSize == front ,空的条件 : front == rear

    ③经过分析我们可以判断出链表中有限数据的个数 (rear+maxSize-front)%maxSize

  代码实现

  1 package DatabaseStructure.com.lsj.queue;
  2 
  3 import java.util.Scanner;
  4 
  5 /**
  6  * Created by IDEA
  7  * 创建人:wen
  8  * 创建日期: 2019-08-12
  9  * 创建时间: 14:42
 10  */
 11 public class CircleArrayQueueDemo {
 12     public static void main(String[] args) {
 13         //测试
 14         CircleQueue queue = new CircleQueue(3);//设置为3说明,他的有效空间是2
 15         char key = ' ';//接收用户输入
 16         Scanner scanner = new Scanner(System.in);
 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             switch (key) {
 26                 case 's':
 27                     queue.showQueue();
 28                     break;
 29                 case 'a':
 30                     System.out.println("输入一个数");
 31                     int val = scanner.nextInt();
 32                     queue.addQueue(val);
 33                     break;
 34                 case 'e':
 35                     scanner.close();
 36                     loop = false;
 37                     break;
 38                 case 'h':
 39                     try {
 40                         int i = queue.headQueue();
 41                         System.out.printf("取出的队列头数据是%d\n", i);
 42                     } catch (Exception e) {
 43                         System.out.println(e.getMessage());
 44                     }
 45                     break;
 46                 case 'g':
 47                     try {
 48                         int i = queue.getQueue();
 49                         System.out.printf("取出的数据是%d\n", i);
 50                     } catch (Exception e) {
 51                         System.out.println(e.getMessage());
 52                     }
 53                     break;
 54                 default:
 55                     System.out.println("输入有误!!!");
 56                     break;
 57             }
 58         }
 59 
 60     }
 61 }
 62 class CircleQueue {
 63     private int maxSize;//表示数组的最大容量
 64     private int front;//队列头
 65     private int rear;//队列尾
 66     private int[] arr; //该数组用于存放数据,模拟队列
 67 
 68     //创建队列的构造器
 69     public CircleQueue(int CimaxSize) {
 70         maxSize = CimaxSize;
 71         arr = new int[maxSize];
 72         front = 0;//指向队列头部,
 73         rear = 0;//指向队列尾,指向队列尾的数据的后一个位置
 74     }
 75 
 76     //判断队列是否满
 77     public boolean isFull() {
 78         return (rear+1)%maxSize == front;
 79     }
 80 
 81     //判断队列是否为空
 82     public boolean isEmpty() {
 83         return rear == front;
 84     }
 85 
 86     //添加数据到队列
 87     public void addQueue(int n) {
 88         //判断队列是否满
 89         if (isFull()) {
 90             System.out.println("队列满,不能加入数据~~");
 91             return;
 92         }
 93 
 94         arr[rear] = n;
 95         rear = (rear+1)%maxSize;
 96     }
 97 
 98     //获取队列数据,出队列
 99     public int getQueue() {
100         //判断队列是否为空
101         if (isEmpty()) {
102             throw new RuntimeException("队列为空");
103         }
104         //这里需要分析出,front是指向队列的第一个元素
105         //1.先把front对应的值保存到一个临时变量
106         //2.将front后移,考虑取模
107         //将临时保存变量返回
108         int i = arr[front];
109         front = (front+1)%maxSize;
110         return i;
111 
112     }
113 
114     //显示队列所有数据
115     public void showQueue() {
116         //遍历
117         if (isEmpty()) {
118             System.out.println("队列为空!!");
119         }
120         //思路:从front开始遍历,遍历多少个元素
121         for (int i = front; i < (front+size()); i++) {
122             System.out.printf("arr[%d]=%d\n", i%maxSize, arr[i%maxSize]);
123         }
124     }
125     //求出当前队列中有效数据的个数
126     public int size(){
127         return (rear+maxSize-front)%maxSize;
128     }
129 
130 
131     //显示队列的头数据,注意不是取出数据
132     public int headQueue() {
133         //判断为空
134         if (isEmpty()) {
135             System.out.println("队列空没有数据");
136         }
137         return arr[front];
138     }
139 }

-----

注 : 链表实现队列,先实现完链表在实现

          

  

posted @ 2019-08-16 16:38  梦才刚刚起航ˇ  阅读(291)  评论(0)    收藏  举报