队列——使用数组实现队列(1)

2.2 队列(使用数组实现队列)


2.2.1 队列的一个使用场景


银行排队的案例:先到先排队,先处理业务

2.2.2 队列介绍


  • 队列是一个有序列表,可以用数组或是链表来实现

  • 遵循先进先出的原则。即:先进入队列的数据,要先取出,后存入的要后取出

  • 示意图:

  •  

  • rear指向队列尾部的数据,front指向队列头部数据的前一位,因为队列从0开始,所以队列的最后一个位置为队列的最大容量 maxSize-1

2.2.3 数组模拟队列思路


  • 队列本身是有序列表,若使用数组的方式来存储队列,则队列数组的声明如上图,其中 maxSize 是该队列的最大容量

  • 因为队列的输入输出分别是从前后端来处理,因此需要两个变量 front 及 rear来分别记录队列的前后端的下标,front会随着数据的输出发生改变,rear会随着队列的数据的输入而改变,如上图所示

  • 当我们将数据存入队列时(addQueue),addQueue的处理需要有两个步骤:

    1. 将尾指针往后移:rear+1

    2. 判断队列是否已满,即尾指针rear是否到达最大值maxSize-1的位置,若队列未满,则将数据存入rear所指的数组元素中

代码实现:

 public class ArrayQueueDemo {
 ​
     public static void main(String[] args) {
 ​
         //简单测试一下
         ArrayQueue arrayQueue = new ArrayQueue(3);
         //接收用户输入
         char key =' ';
         Scanner scanner = new Scanner(System.in);
         boolean loop = true;
         //输出一个菜单
         while (loop){
             System.out.println("s(show): 显示队列");
             System.out.println("e(exit): 退出程序");
             System.out.println("a(add): 添加数据到队列");
             System.out.println("g(get): 从队列取出数列");
             System.out.println("h(head): 查看队列头的数据");
             //接受字符
             key = scanner.next().charAt(0);
             switch (key){
                 case 's':
                     arrayQueue.showQueue();
                     break;
                 case 'e':
                     scanner.close();
                     loop = false;
                     break;
                 case 'a':
                     System.out.println("请输入一个数:");
                     int i = scanner.nextInt();
                     arrayQueue.addQueue(i);
                     break;
                 case 'g':
                     arrayQueue.getQueue();
                     break;
                 case 'h':
                     System.out.println("队列头的数据为:");
                     arrayQueue.getFront();
                     break;
                 default: break;
             }
         }
         System.out.println("程序退出");
     }
 ​
 }
 ​
 /**
  * 使用数组模拟队列
  */
 class ArrayQueue{
 ​
     /**
      * 表示数组的最大容量
      */
     private int maxSize;
     /**
      * 队列头
      */
     private int front;
     /**
      * 队列尾
      */
     private int rear;
     /**
      * 用于存放队列中的数据,模拟队列
      */
     private int[] arr;
 ​
     /**
      * 创建队列的构造器
      */
     public ArrayQueue(int maxSize){
         this.maxSize = maxSize;
         arr = new int[maxSize];
         //指向队列头部,指向队列头的前一个数据
         front = -1;
         //指向队列尾部,直接指向队列尾部的数据
         rear = -1;
     }
 ​
     /**
      * 判断队列是否满
      */
     public boolean isFull(){
         return rear + 1 == maxSize;
     }
 ​
     /**
      * 判断队列是否为空
      */
     public boolean isEmpty(){
         return rear == front;
     }
 ​
     /**
      * 添加数据到队列
      */
     public void addQueue(int m){
         //判断队列是否满
         if (isFull()){
             System.out.println("队列已满,不能再添加数据");
             return;
         }
         //rear后移,并将数据存入其中
         rear++;
         arr[rear] = m;
     }
 ​
     /**
      * 出队列,获取队列的数据
      */
     public void getQueue(){
         //判断队列是否为空
         if (isEmpty()){
             System.out.println("队列为空,没有数据可以获取了");
             return;
         }
         //front后移
         front++;
         System.out.println("获取到的数据为:"+arr[front]);
     }
 ​
     /**
      * 显示队列的所有数据
      */
     public void showQueue(){
         //判断队列是否为空
         if (isEmpty()){
             System.out.println("队列为空,没有数据可以获取了");
             return;
         }
         for (int i=0;i< arr.length;i++){
             System.out.printf("arr[%d]=%d\n",i,arr[i]);
         }
     }
 ​
     /**
      * 显示队列的头数据,注意:不是取数据
      */
     public void getFront(){
         if (isEmpty()){
             System.out.println("队列为空,没有数据可以获取了");
             return;
         }
         System.out.println("队列的头数据为:"+arr[front+1]);
     }
 ​
 }

问题分析并优化:

  • 问题:目前数组使用一次就不能再次使用,没有达到复用的效果

  • 将这个数组使用算法,改进成一个环形数组(下一期)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值