队列是一个有序的列表,可以用数组或是链表来实现。队列遵循先入先出的规则,就像排队一样,先存入队列的数据需要先取出,后存入的数据需要后取出,而在队列中,添加数据是在队列尾部,取数据则是在队列头部。
这篇文章主要讲的是数组模拟队列的实现:
队列本身就是有序列表,若是使用数组的结构来存储队列的数据,则队列数组的maxSize就是该队列的最大容量,而由于队列的输出,输入分别是从前后端来处理,因此需要两个变量front和rear分别记录队列前后端的下标,front会随着数据输出而改变,rear则是随着数据输入而改变。
比如当我们将数据存入队列时称为“addQueue”,addQueue的处理需要两个步骤:
(1)将尾指针往后移:rear+1,而当front=rear=-1时,队列为空
(2)若尾指针rear小于队列的最大下标 maxSize-1时,则将数据存入rear所指的数组元素中,否则无法存入输出,因为队列数组已经满了,当rear=maxSize-1时,认为队列是满的,这是因为在Queue中,rear和front都是从-1开始。
下面附上一些方法的代码来帮助大家理解如何操作队列:
//判断队列是否满 public boolean isFull(){ return rear== maxSize-1; }
上面的代码是判断队列是否满
//判断队列是否为空 public boolean isEmpty(){ return rear == front; }
该代码用于判断队列是否为空
public void addQueue(int n){ if(isFull()){ System.out.println("队列满,不能加入数据"); return; } rear++; arr[rear] = n; }
addQueue方法是将数据填入队列当中,条件是队列未满
//获取队列的数据,出队列 public int getQueue(){ if(isEmpty()){ System.out.println("队列空,不能取出数据"); //通过抛出异常 throw new RuntimeException("队列空,不能取出数据"); } front++; return arr[front]; }
getQueue方法是获得队列的头部数据,并将数据出队列
//显示队列的所有数据 public void showQueue(){ if(isEmpty()){ System.out.println("队列为空,没有数据"); return; } for(int i=0;i< arr.length;i++){ System.out.print(arr[i]+"\t"); } }
showQueue方法是显示队列的全部数据,前提是队列不能为空
//显示队列的头数据,注意不是取出数据 public int headQueue(){ if(isEmpty()) { System.out.println("队列为空,没有数据"); throw new RuntimeException("队列空,不能取出数据"); } return arr[front+1]; }
headQueue方法是显示队列的头部数据,与getQueue的区别就是并不将头部数据取出,仅仅是显示头部数据。
//创建队列的构造器 public ArrayQueue(int arrMaxSize){ maxSize = arrMaxSize; arr = new int[maxSize]; front = -1; //指向队列头部的前一个位置,并不包含数据 rear = -1; //指向队列尾部,指向队列尾的数据(即就是队列最后一个数据) }
我们同时也创建了队列的构造器。
以上就是方法的代码,最终附上测试的全部代码和运行截图:
* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */package queue;import java.util.Scanner;/** * * @author Administrator */public class ArrayQueueDemo { public static void main(String[] args){ //测试 //创建一个队列 ArrayQueue queue = new ArrayQueue(3); char key = ' ';//接收用户输入 Scanner input = 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(hrad):查看队列头的数据"); key = input.next().charAt(0); switch(key){ case 's': queue.showQueue(); break; case 'a': System.out.println("输入一个数"); int value = input.nextInt(); queue.addQueue(value); break; case 'g': try{ int res =queue.getQueue(); System.out.println("取出的数据是"+ res); } catch(Exception e){ System.out.println(e.getMessage()); } break; case 'h': //查看队列头的数据 try{ int res =queue.headQueue(); System.out.println("取出的队列头数据是"+ res); } catch(Exception e){ System.out.println(e.getMessage()); } break; case 'e': input.close(); loop = false; break; default: break; } } System.out.println("程序退出"); }}//使用数组模拟队列-编写一个ArrayQueue类class ArrayQueue{ private int maxSize; //表示数组的最大容量 private int front ; //队列头 private int rear; //队列尾 private int[] arr; //该数据用于存放数据,模拟队列 //创建队列的构造器 public ArrayQueue(int arrMaxSize){ maxSize = arrMaxSize; arr = new int[maxSize]; front = -1; //指向队列头部的前一个位置,并不包含数据 rear = -1; //指向队列尾部,指向队列尾的数据(即就是队列最后一个数据) } //判断队列是否满 public boolean isFull(){ return rear== maxSize-1; } //判断队列是否为空 public boolean isEmpty(){ return rear == front; } //添加数据到队列 public void addQueue(int n){ if(isFull()){ System.out.println("队列满,不能加入数据"); return; } rear++; arr[rear] = n; } //获取队列的数据,出队列 public int getQueue(){ if(isEmpty()){ System.out.println("队列空,不能取出数据"); //通过抛出异常 throw new RuntimeException("队列空,不能取出数据"); } front++; return arr[front]; } //显示队列的所有数据 public void showQueue(){ if(isEmpty()){ System.out.println("队列为空,没有数据"); return; } for(int i=0;i< arr.length;i++){ System.out.print(arr[i]+"\t"); } } //显示队列的头数据,注意不是取出数据 public int headQueue(){ if(isEmpty()) { System.out.println("队列为空,没有数据"); throw new RuntimeException("队列空,不能取出数据"); } return arr[front+1]; }}
测试案例中,我将队列的长度设为3,方便测试,运行截图如下:
程序正确运行,不过目前也出现了一些问题,那就是目前数组使用一次就不能继续使用,没有达到复用的效果,那么我们可以使用算法将这个数组改进成一个环形队列,来解决这个问题,我们会在下一篇文章中进行讲解。