文章内容选自尚硅谷数据结构与算法,jdk8,eclipse环境
非循环队列
创建一个数组长度为3的队列,front指向队列第一个元素的前一个位置,rear表示指向队列最后一个位置。代码如下
package com.atguigu;
import java.util.Scanner;
import javax.management.RuntimeErrorException;
public class ArrayQueueDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayQueue arr = new ArrayQueue(3);
boolean loop = true;
char key = ' ';
while(loop){
System.out.println("a(addInt)");
System.out.println("g(getInt)");
System.out.println("d(display)");
System.out.println("h(getHead)");
System.out.println("e(exit)");
key = scanner.next().charAt(0);
switch (key){
case 'a':
int n = scanner.nextInt();
arr.addInt(n);break;
case 'g': try{
System.out.printf("输出的结果为%d",arr.getInt());
System.out.println();
}catch(RuntimeException e){
System.out.println(e.getMessage());
}
break;
case 'd': arr.display();break;
case 'h': try{
System.out.printf("输出的结果为%d",arr.getHead());
System.out.println();
}catch(RuntimeException e){
System.out.println(e.getMessage());
};break;
case 'e':
System.out.println("程序退出");
loop = false;
scanner.close();
break;
default :
scanner.close();
break;
}
}
System.out.println("程序结束");
}
}
class ArrayQueue{
private int maxSize;
private int[] arr;
private int rear = -1;
private int front = -1;
public ArrayQueue(int maxsize){
maxSize = maxsize;
arr = new int[maxSize];
}
public boolean isFull(){
return rear == maxSize -1;
}
public boolean isEmpty(){
return rear == front;
}
public void addInt(int n){
boolean isFull = isFull();
// Scanner scanner = new Scanner(System.in);
if(isFull)
System.out.println("队列已满,请勿输入");
else
{
// arr[++front] = scanner.nextInt();
// scanner.close();
arr[++rear] = n;
}
}
public int getInt(){
boolean isEmpty = isEmpty();
if(isEmpty)
throw new RuntimeException("队列已空,无法取值");
else
return arr[++front];
}
public void display(){
boolean isEmpty = isEmpty();
if (isEmpty == false) {
for (int i = 0; i < arr.length; i++) {
System.out.printf("a[%d] = %d\t", i, arr[i]);
}
}else
{
System.out.println("队列已空");
}
System.out.println();
}
public int getHead(){
boolean isEmpty = isEmpty();
if(isEmpty)
throw new RuntimeException("队列已空");
else
return arr[front+1];
}
}
代码缺陷:只能使用一次,不能循环使用;display始终打印数组全部的值,不能打印有效值。
循环队列
rear表示指向队列最后一个元素的下一个元素,front表示指向队列的第一个元素。用取模%运算做循环队列
此代码中,数组长度为4,但队列长度为3.若数组长度为n,队列长度就为n-1.
示例代码如下
package com.atguigu;
import java.util.Scanner;
public class CircleArrayQueueDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
CircleArr circleArr = new CircleArr(4);
boolean loop = true;
char key = ' ';
while(loop){
System.out.println("a(addInt)");
System.out.println("g(getInt)");
System.out.println("s(show)");
System.out.println("h(getHead)");
System.out.println("e(exit)");
key = scanner.next().charAt(0);
switch(key){
case 'a' :
int n = scanner.nextInt();
circleArr.addInt(n);
break;
case 'g' :
try {
System.out.printf("取出的值为%d",circleArr.getInt());
System.out.println();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
break;
case 's' :
circleArr.show();
break;
case 'h' :
try {
circleArr.getHead();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
break;
case 'e' :
scanner.close();
loop = false;
System.out.println("退出队列");
break;
default :
scanner.close();
break;
}
}
System.out.println("程序运行结束");
}
}
class CircleArr{
private int rear;
private int front;
private int arr[];
private int maxSize;
public CircleArr(int max){
maxSize = max;
arr = new int[maxSize];
}
public boolean isFull(){
return ((rear+1)%maxSize) == front;
}
public boolean isEmpty(){
return rear == front;
}
public void addInt(int n){
boolean isFull = isFull();
if(isFull){
System.out.println("数组已满,无法添加");
}
else
{
arr[rear] = n;
rear = (rear+1)%maxSize;
System.out.println("添加完毕");
}
}
public int getInt(){
boolean isEmpty = isEmpty();
if(isEmpty)
throw new RuntimeException("数组已空,无法取值");
int value = arr[front];
front =(front +1)%maxSize;
return value;
}
public void show(){
boolean isEmpty = isEmpty();
if(isEmpty){
System.out.println("数组已空");
}
else{
for(int i = front;i<(rear+maxSize-front)%maxSize;i++){
System.out.printf("a[%d] = %d\t",i%maxSize,arr[i%maxSize]);
}
System.out.println();
}
}
public void getHead(){
boolean isEmpty = isEmpty();
if(isEmpty){
throw new RuntimeException("数组已空");
}
else{
System.out.println(arr[front]);
}
}
}
分析代码
判断数组已满的语句发生了变化
public boolean isFull(){
return ((rear+1)%maxSize) == front;
}
此语句表明凡是rear指向的空间都为空。
在show方法中
for(int i = front;i<front+(rear+maxSize-front)%maxSize;i++){
System.out.printf("a[%d] = %d\t",i%maxSize,arr[i%maxSize]);
}
System.out.println();
front+(rear+maxSize-front)%maxSize 表示队列有效元素的个数,i%maxSize确保从队列首元素到尾元素输出。
rear使用通过取模保持循环
rear = (rear+1)%maxSize;
运行结果为
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
a
1
添加完毕
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
a
2
添加完毕
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
a
3
添加完毕
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
s
a[0] = 1 a[1] = 2 a[2] = 3
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
g
取出的值为1
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
s
a[1] = 2 a[2] = 3
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
a
4
添加完毕
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
s
a[1] = 2 a[2] = 3 a[3] = 4
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
g
取出的值为2
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
s
a[2] = 3 a[3] = 4
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
a
5
添加完毕
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
s
a[2] = 3 a[3] = 4 a[0] = 5
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
h
3
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
g
取出的值为3
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
g
取出的值为4
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
g
取出的值为5
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
s
数组已空
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
h
数组已空
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)
g
数组已空,无法取值
a(addInt)
g(getInt)
s(show)
h(getHead)
e(exit)