(一)介紹

隊列(queue)是一種線性資料結構。與同為線性資料結構的棧不同的是隊列中的元素遵循的是先進先出(First In First Out)的規則,和在現實中排隊一樣,講究的是先來後到的原則。隊列出口端叫做隊頭(front),隊列的入口端叫做隊尾(rear)。
(二)基本操作
(1)入隊
(2)出隊
(3)判斷隊列是否已空
(4)判斷隊列是否已滿
(5)擷取隊頭元素
I .入隊
說明:就是通過rear的移動來實作元素的入隊,rear始終指向棧頂
II.出隊
說明:出隊是在隊尾進行,通過left的移動來進行的
(三)代碼實作
package arrayqueue;
import java.util.Scanner;
/**
* @author Jin
* @ Date 2022年06月2022/6/29日0:08
* 通過數組來實作隊列
*/
public class ArrayQueueRealize {
public static void main(String[] args) {
//建立一個對象
ArrayQueue t1=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):檢視隊列頭的資料");
System.out.println("請輸入具體操作:");
key =scanner.next().charAt(0);
//接收一個字元
switch(key){
case's':t1.show();break;
case'a':
System.out.println("輸出一個數");
int value =scanner.nextInt();
t1.addQueue(value);break;
case'g':try{
int res=t1.getQueue();
System.out.printf("取出的資料是%d\n ",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case'h':
try{
int res=t1.headQueue();
System.out.printf("隊列頭的資料是%d",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case'e':scanner.close();
loop=false;
break;
default:break;
}
}
System.out.println("程式退出!!!");
}
}
/**使用數組模拟隊列---編寫一個ArrayQueue類*/
class ArrayQueue{
public int maxSize;
private int front;
/**隊列頭*/
private int rear;
/**隊列尾*/
private int[]arr;
/*該數組用于存放資料,模拟隊列*/
/**建立隊列的構造器(資料進行初始化)*/
public ArrayQueue(int maxSize){
this.maxSize=maxSize;
arr=new int[maxSize];
/*表示數組的最大容量*/
front = -1;
//指向隊列頭部,分析出front是指向隊列頭的前一個位置
rear = -1;
//指向隊列尾,指向隊列尾的資料(即就是隊列的最後一個資料)
}
/**(1)判斷隊列是否滿*/
public boolean isFull(){
return rear==maxSize-1;
}
/**(2)判斷隊列是否為空*/
public boolean isEmpty(){
return rear==front;
}
/**(3)添加資料到隊列*/
public void addQueue(int n){
//判斷隊列是否已經滿
if(isFull()){
System.out.println("隊列滿,不能加入資料!!");
}
rear++;//rear後移
arr[rear]=n;
}
/**(4)擷取隊列的資料(出隊列)*/
public int getQueue() {
//判斷隊列是否是空的
if (isEmpty()) {
throw new RuntimeException("隊列空,不能取資料");
//通過抛出異常
}else{
front++;//front後移
int middle=arr[front];
arr[front]=0;
//取出後空間值置為0
return middle;
}
}
/**(5)顯示隊列的資料*/
public void show(){
if(isEmpty()){
System.out.println("隊列為空,沒有資料");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.printf("arr[%d]=%d ",i,arr[i]);
}
}
/**(6)顯示隊列的頭資料(并不取資料)*/
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("隊列空的,沒有資料");
}
return arr[front+1];
}
}
存在的問題??
由于隊列隻能在隊頭入隊,隊尾出隊,是以就限定了數組空間隻能使用一次,而不能夠重複利用
改進方案
分析:
package arrayqueue;
import java.util.Scanner;
/**
* @author Jin
* @ Date 2022年06月2022/6/29日10:13
*/
public class CircleArrayQueue {
public static void main(String[] args) {
System.out.println("測試數組模拟環形隊列的案例~~~~");
//建立一個對象
ArrayQueue1 t1=new ArrayQueue1(4);
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):檢視隊列頭的資料");
System.out.println("請輸入具體操作:");
key =scanner.next().charAt(0);
//接收一個字元
switch(key){
case's':t1.show();break;
case'a':
System.out.println("輸出一個數");
int value =scanner.nextInt();
t1.addQueue(value);break;
case'g':try{
int res=t1.getQueue();
System.out.printf("取出的資料是%d\n ",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case'h':
try{
int res=t1.headQueue();
System.out.printf("隊列頭的資料是%d",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case'e':scanner.close();
loop=false;
break;
default:break;
}
}
System.out.println("程式退出!!!");
}
}
/**使用數組模拟隊列---編寫一個ArrayQueue類*/
class ArrayQueue1{
public int maxSize;
private int front;
/**隊列頭*/
private int rear;
/**隊列尾*/
private int[]arr;
/*該數組用于存放資料,模拟隊列*/
/**建立隊列的構造器(資料進行初始化)*/
public ArrayQueue1(int maxSize){
this.maxSize=maxSize;
arr=new int[maxSize];
/*表示數組的最大容量*/
front = 0;
//指向隊列頭部,分析出front是指向隊列頭的第一個位置
rear = 0;
//指向隊列尾,指向隊列尾的資料的後一個位置
}
/**(1)判斷隊列是否滿*/
public boolean isFull(){
return (rear+1)%maxSize==front;
}
/**(2)判斷隊列是否為空*/
public boolean isEmpty(){
return rear==front;
}
/**(3)添加資料到隊列*/
public void addQueue(int n){
//判斷隊列是否已經滿
if(isFull()){
System.out.println("隊列滿,不能加入資料!!");
}
arr[rear]=n;
//先添加資料
rear=(rear+1)%maxSize;
//rear後移,防止rear越界
}
/**(4)擷取隊列的資料(出隊列)*/
public int getQueue() {
//判斷隊列是否是空的
if (isEmpty()) {
throw new RuntimeException("隊列空,不能取資料");
//通過抛出異常
}else{
//這裡需要分析出front是指向隊列的第一個元素
//(1)先把front對應的值保留到一個臨時變量
//(2)将front後移,考慮取模
//(3)将臨時儲存的變量傳回
int value=arr[front];
front=(front+1)%maxSize;
return value;
}
}
/**(5)顯示隊列的資料*/
public void show(){
if(isEmpty()){
System.out.println("隊列為空,沒有資料");
return;
}
//從front開始周遊,周遊多少個元素
for (int i = front; i < front+getMaxSize(); i++) {
System.out.printf("arr[%d]=%d ",i%maxSize,arr[i%maxSize]);
}
}
//求出目前隊列的有效資料
public int getMaxSize(){
return (rear-front+maxSize)%maxSize;
}
/**(6)顯示隊列的頭資料(并不取資料)*/
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("隊列空的,沒有資料");
}
return arr[front];
}
}