队列

更多内容,前往 IT-BLOG

队列是一个有序列表,可以用数组或是链表来实现。遵循先入先出的原则。

数组模拟环形队列


【1】队列本身是有序列表,若使用数组的结构来存储队列数据,队列数组的声明如下,其中 maxSize 是该队列的最大容量;
 
【2】因为队列的输入输出是分别从头和尾来处理的,因此需要两个变量 front(头)=0 和 tail(尾)=0 ,tail会随着数据的输入而变化,front 会随着数据的输出而变化。
【3】为了充分利用数组,例如上图:当tail == maxSize 时,可以继续向 index = 0 的空下标中存放数据。此时就将数组看做一个环形数组(通过取模的方式来实现)。

分析环形数组实现思路:【1】尾(tail)索引的下一个为头(front)索引表示队列为满(因为判断空和判断满冲突,因此需要空出一个格子来做一个约定,相当于最多只能存放 maxSize - 2 的数据,浪费一个格子)这里判断队列满的公式:(tail+1)%maxSize == front ;用一张图来说明问题:

代码实现如下:

  1 package com.algorithms;
  2 
  3 import java.util.Scanner;
  4 
  5 /**
  6  * Created by Administrator on 2019/11/2 0002.
  7  */
  8 public class CircleQueue {
  9     //定义一个数组
 10     private int[] arr;
 11     //数组的最大值
 12     private int maxSize;
 13     //头指针
 14     private int front;
 15     //尾指针
 16     private int tail;
 17 
 18     //创建一个带参的构造器,出入队列的大小
 19     public CircleQueue(int maxSize){
 20         this.maxSize = maxSize;
 21         arr = new int[maxSize];
 22     }
 23 
 24     //数据测试
 25     public static void main(String[] args) {
 26         CircleQueue circleQueue = new CircleQueue(5);
 27         System.out.println("根据提示输入相关值");
 28         Scanner in = new Scanner(System.in);
 29         while (true){
 30             System.out.println("s:显示");
 31             System.out.println("o:输入");
 32             System.out.println("p:输出");
 33             System.out.println("h:头出");
 34             String next = in.next();
 35             switch (next){
 36                 case "s" : circleQueue.list(); break;
 37                 case "o" :
 38                     System.out.println("请输入一个数");
 39                     int i = in.nextInt();
 40                     circleQueue.offer(i);
 41                     break;
 42                 case "p" :
 43                     int poll = circleQueue.poll();
 44                     System.out.println(poll);
 45                     break;
 46                 case "h" :
 47                     int peek = circleQueue.peek();
 48                     System.out.println(peek);
 49                     break;
 50             }
 51         }
 52     }
 53 
 54     //判断队列是否已满,根据我们的约定来,虽然它还能存放一个元素。
 55     //这里面没几个难点。。。这算一个**********************
 56     public boolean isFull(){
 57         return (tail + 1) % maxSize == front;
 58     }
 59     //插入方法
 60     public void offer(int num){
 61         if(isFull()){
 62             throw  new RuntimeException("队列已满");
 63         }
 64         arr[tail]=num;
 65         //不能直接 ++ 否则可以数据越界
 66         //这里面没几个难点。。。这算一个**********************
 67         tail = (tail + 1) % maxSize;
 68     }
 69 
 70     //判断队列是否为空
 71     public boolean isEmpty(){
 72         return tail == front;
 73     }
 74 
 75     public int poll(){
 76         if(isEmpty()){
 77             throw new RuntimeException("队列为空");
 78         }
 79         int temp = arr[front];
 80         //不能直接 ++ 否则可以数据越界
 81         front = (front + 1) % maxSize;
 82         return temp;
 83     }
 84 
 85     //查看队列的大小
 86     public int size(){
 87         //tail+maxSize 是防止队列存满后,tail=2 在 front=3 的前面这种为负数的情况
 88         // %maxSize 是防止计算的结果大于 maxSize
 89         //这里面没几个难点。。。这算一个**********************
 90         return (tail+maxSize-front)%maxSize;
 91     }
 92 
 93     //循环查看所有元素信息
 94     public void list(){
 95         for(int i = front;i< front + size();i++){
 96             System.out.printf("arr[%d]==%d\n",i%maxSize,arr[i%maxSize]);
 97         }
 98     }
 99 
100     //查看栈顶元素
101     public int peek(){
102         return arr[front];
103     }
104 }
 
posted @ 2020-11-24 07:31  Java程序员进阶  阅读(99)  评论(0编辑  收藏  举报