队列:队列是一个有序列表,可以用数组(顺序表)或是链表来实现。
遵循先入先出的原则。即先存入队列的数据,要先取出。后存入的数据要后取出
数组模拟队列
队列本身是有序列表,若使用数组的结构来存储队列的数据,maxSize是该队列的最大容量。因为队列的输入、输出是分别从前后端来处理,因此需要两个变量front和rear分别记录队列前后端的下标,front会随着数据输出改变,rear随着数据的输入改变。
当我们将数据存入队列时称为addQueue,addQueue的处理需要有两个步骤
思路分析:1)将尾指针后移:rear+1 当front==reat空
2)若尾指针rear小于队列的最大下标maxSize-1时,将数据存入rear所指的数组中,否则无法存入数据。Rear==maxSize-1队列满

代码实现见代码
问题分析优化:目前数组使用一次就不能用,没有达到复用的效果
将这个数组使用算法,改进成一个环形的队列 取模:%
数组模拟环形队列
思路:
1.front变量的含义做一个调整:front指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素,front的初始值为0;
2.rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置。因为希望空出一个空间作为约定,rear初始值=0;
3.当队列满时,条件是:(rear+1)%maxSize==front(maxSize永远比rear大,若不在最后一位,除以maxSize也是白除还是rear+1)
4.当队列为空的条件:rear==front
5.当我们这样分析,队列中有效数据的个数:(rear+maxSize-front)%maxSize
目录
数组模拟队列
package 队列;
import java.util.Scanner;
//数组模拟队列
public class ArrayQueueDemo {
public static void main(String[] args) {
ArrayQueue queue=new ArrayQueue(5);
Scanner s=new Scanner(System.in);
boolean loop=true;
//输出一个菜单
while (loop){
System.out.println("输入1:向队列中增加数据");
System.out.println("输入2:从队列中取出数据");
System.out.println("输入3:展示队列中所有数据");
System.out.println("输入4:展示第一个数");
System.out.println("输入5:退出程序");
switch (s.next().charAt(0)){
case '1':
System.out.println("请向队列中增加数据");
queue.addQueue(s.nextInt());
System.out.println("增加成功");
break;
case '2':
System.out.println("从队列中取出数据");
try {
int result=queue.getQueue();
System.out.println("取出成功,取出的数据是:"+result);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '3':
System.out.println("展示队列中所有数据");
try {
queue.showAll();
System.out.println("展示成功!");
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '4':
System.out.println("展示第一个数据");
int firstDate=queue.showFirst();
System.out.println("第一个数据是:"+firstDate);
break;
case '5':
System.out.println("程序退出!");
break;
default:
break;
}
}
System.out.println("程序退出!");
}
}
class ArrayQueue{
private int arrmaxSize;
private int[] arr;//该数据用于存放数据,模拟队列
private int rear;//队列尾
private int front;//队列
//设定数组的长度
public ArrayQueue(int arrmaxSize){
this.arrmaxSize=arrmaxSize;
arr=new int[arrmaxSize];
rear=-1;//指向队列尾最后一数据
front=-1;//指向队列头部,front是指向头第一个数据的前面
}
//判断是否满队列
public boolean isFull(){
return rear==arrmaxSize-1;
}
//判断是否为空队列
public boolean isEmpty(){
return rear==front;
}
//向队列中增加数据
public void addQueue(int n){
if(isFull()){
System.out.println("队列已满");
return;
}else{
rear++;
arr[rear]=n;
}
}
//从队列中取数据(要获取值,所以返回int)
public int getQueue(){
if(isEmpty()){
//如果返回值会不清晰所以抛出异常,抛出异常就不用再返回值的
throw new RuntimeException("队列为空");
}
front++;//一个一个取出
return arr[front];
}
//展示队列的所有数据
public void showAll(){
if(isEmpty()){
System.out.println("队列为空!");
return;
}
for(int i=0;i<arr.length;i++){
System.out.println("arr"+"["+i+"]"+"="+arr[i]);
}
}
//展示第一个数据(不是取出)
public int showFirst(){
if(isEmpty()){
throw new RuntimeException("队列为空!");
}
return arr[rear+1];//只有第一个数
}
}
数组模拟环形队列
package 队列;
import java.util.Scanner;
public class CirlceArrayQueueDemo {
public static void main(String[] args) {
CircleArray queue=new CircleArray(5);//长度为5,最大有效数据有四个
Scanner s=new Scanner(System.in);
boolean loop=true;
//输出一个菜单
while (loop){
System.out.println("输入1:向队列中增加数据");
System.out.println("输入2:从队列中取出数据");
System.out.println("输入3:展示队列中所有数据");
System.out.println("输入4:展示第一个数");
System.out.println("输入5:退出程序");
switch (s.next().charAt(0)){
case '1':
System.out.println("请向队列中增加数据");
queue.addQueue(s.nextInt());
System.out.println("增加成功");
break;
case '2':
System.out.println("从队列中取出数据");
try {
int result=queue.getQueue();
System.out.println("取出成功,取出的数据是:"+result);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '3':
System.out.println("展示队列中所有数据");
try {
queue.showAll();
System.out.println("展示成功!");
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '4':
System.out.println("展示第一个数据");
int firstDate=queue.showFirst();
System.out.println("第一个数据是:"+firstDate);
break;
case '5':
System.out.println("程序退出!");
break;
default:
break;
}
}
System.out.println("程序退出!");
}
}
class CircleArray{
private int arrmaxSize;
private int[] arr;//该数据用于存放数据,模拟队列
private int rear;//rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置。因为希望空出一个空间作为约定,rear初始值=0;
private int front;//front变量的含义做一个调整:front指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素,front的初始值为0;
public CircleArray(int arrmaxSize){
this.arrmaxSize=arrmaxSize;
arr=new int[arrmaxSize];
front=0;
rear=0;//默认都为0,可写可不写
}
public boolean isFull(){
return (rear+1)%arrmaxSize==front;
}
public boolean isEmpty(){
return rear==front;
}
public void addQueue(int n){
if(isFull()){
System.out.println("队列已满");
return;
}else{
arr[rear]=n;
//将rear后移,这里必须考虑取模
rear=(rear+1)%arrmaxSize;
}
}
//从队列中取数据(要获取值,所以返回int)
public int getQueue(){
if(isEmpty()){
//如果返回值会不清晰所以抛出异常,抛出异常就不用再返回值的
throw new RuntimeException("队列为空");
}
//这里分析数front是指向队列的第一个元素
//1.先把front对应的值给一个临时变量
//2.将front后移,考虑在最后的位置,取模
//3.将临时变量值返回
int value=arr[front];
front=(front+1)%arrmaxSize;
return value;
}
public void showAll(){
if(isEmpty()){
System.out.println("队列为空!");
return;
}
for(int i=front;i<front+(rear+arrmaxSize-front)%arrmaxSize;i++){
System.out.println("arr"+"["+i%arrmaxSize+"]"+"="+arr[i%arrmaxSize]);
}
}
public int showFirst(){
if(isEmpty()){
throw new RuntimeException("队列为空!");
}
return arr[rear];//只有第一个数
}
}
本文探讨了如何使用Java通过数组模拟队列,遵循先入先出原则。接着讲解了如何优化成环形队列,以提高数组的复用效率,通过取模运算实现元素的插入和移除。详细代码实现和问题分析包含在目录中。
509

被折叠的 条评论
为什么被折叠?



