天天看點

Java實作數組模拟(環形)隊列

Java實作數組模拟(環形)隊列

了解隊列

通俗的說,隊列就跟你在超市排隊結賬一樣。結賬的人排了一隊,那先來的人在隊首,會先結賬,後來的人隻能從隊伍後面排隊,不能插隊,後結賬。結賬隻能從第一個人開始結賬,收銀員不可能放着第一個人不管,先去給後面的人結賬,第一個人結賬完,就走了,後面的人依次向前。還有一點是 隊伍中每個人都是在挨着的,是以隊列有記憶體中的存儲是連續的。

用百度百科的話講:隊列是一種特殊的線性表,特殊之處在于它隻允許在表的前端(front)進行删除操作,而在表的後端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。

用數組實作隊列

1. 建立隊列

經過思考,隊列應該有隊首、隊尾、隊列長度、數組這幾部分組成,應該有添加資料、取出資料、周遊隊列的功能。我們先把隊列的架構搭好,稍後分析每一塊應該怎麼寫。

package chengquan.dataStru;
/*
chengquan 20200925 用數組實作隊列
*/
public class MyQueue {
    private int front;  // 隊首
    private int rear;   // 隊尾
    private int queueSize; // 隊列長度
    private int[] array; // 隊列資料存儲到數組裡

    public MyQueue(int queueSize){
        // 剛執行個體化一個隊列的時候,隊裡沒有元素,
        this.front = -1;
        this.rear = -1;
        this.queueSize = queueSize;
        this.array = new int[queueSize+1];
    }
    /*
    判斷隊列是否為空
    */
	public Boolean isEmpty(){
	}
    /*
   判斷隊列是滿了
    */
    public Boolean isFull(){
    }
    /*
    實作功能:向隊列中添加一個元素
     */
    public void addData(int data){
    }

    /*
    實作功能:從隊列中取出一個元素
     */
    public void getData(){
    }

    /*
    周遊
     */
    public void list(){
    }
}
           

2. 判斷隊列是否滿了

當隊列資料存滿的時候,rear 應該指向數組的最後一個元素,最後一個元素的下标是 size -1。

public Boolean isFull(){
	return rear == queueSize - 1;
}
           

3. 判斷隊列是否為空

隊列為空的時候就是隊列頭等于隊列尾的下标

public Boolean isEmpty(){
	return front == rear;
}
           

4. 實作隊列的添加資料到末尾

每添加一個資料,rear就要往後移一位,将資料放到rear裡。

public void addData(int data){
    if(!isFull()){
        rear = rear + 1;
        array[rear] =data;
    }else {
        System.out.println("隊列已經爆滿了!!");
    }
}
           

5. 實作隊列的取出資料

public void getData(){
    if(!isEmpty()){
        front = front + 1;
        System.out.println("取出的資料為:" +  array[front]);
        array[front] = 0;
    }else {
        System.out.println("隊列為空");
    }
}
           

6. 周遊數列

public void list(){
    if (isEmpty()){
        System.out.println("隊列是空的");
    }
    for (int i = front + 1; i <= rear; i++) {
        System.out.print(array[i] + " ");
    }
    System.out.println();
}
           

7. 整合

package chengquan.dataStru;

public class MyQueue {
    private int front;  // 隊首
    private int rear;   // 隊尾
    private int queueSize; // 隊列長度
    private int[] array;
    public MyQueue(){

    }

    public MyQueue(int queueSize){
        // 剛執行個體化一個隊列的時候,隊裡沒有元素,
        this.front = -1;
        this.rear = -1;
        this.queueSize = queueSize;
        this.array = new int[queueSize+1];
    }
    /*
    判斷隊列是否為空
     */
    public Boolean isEmpty(){
        return front == rear;
    }

    /*
   判斷隊列是滿了
    */
    public Boolean isFull(){
        return rear == queueSize -1;
    }
    /*
    實作功能:向隊列中添加一個元素
     */
    public void addData(int data){
        if(!isFull()){
            rear = rear + 1;
            array[rear] =data;
        }else {
            System.out.println("隊列已經爆滿了!!");
        }
    }

    /*
    實作功能:從隊列中取出一個元素
     */
    public void getData(){
        if(!isEmpty()){
            front = front + 1;
            System.out.println("取出的資料為:" +  array[front]);
            array[front] = 0;
        }else {
            System.out.println("隊列為空");
        }
    }

    /*
    周遊
     */
    public void list(){
        if (isEmpty()){
            System.out.println("隊列是空的");
        }
        for (int i = front + 1; i <= rear; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
}
           

8. 測試

MyQueue myQueue = new MyQueue(5);

myQueue.list();

myQueue.addData(666);
myQueue.addData(999);

myQueue.list();

myQueue.getData();

myQueue.list();
/*
輸出結果為:

隊列是空的

666 999 
取出的資料為:666
999 
*/
           

9.發現問題

當進行多次資料插入取出之後,我發現了一個問題:建立了一個長度為5的隊列,往隊列裡插入了1、2、3、4、5五個資料,接着又取出了隊列的第一個資料1,隊列裡還剩下資料2、3、4、5,到這裡為止都還是正常的。接下來又往隊列裡再添加資料的時候卻提示隊列已經滿了。

經過研究發現是了原因:取出元素的時候,隊首往後移動一位,

– 插入圖檔

這個時候,我們要考慮實作一個循環隊列,将數組首尾相接,類似于左輪槍一樣,實作空間的再次利用。

MyQueue myQueue = new MyQueue(5);

myQueue.list();

myQueue.addData(1);
myQueue.addData(2);
myQueue.addData(3);
myQueue.addData(4);
myQueue.addData(5);

myQueue.list();

myQueue.getData();

myQueue.list();

myQueue.addData(6);
/* 輸出結果為:
隊列是空的

1 2 3 4 5 
取出的資料為:1
2 3 4 5 
隊列已經爆滿了!!
*/       
           

用數組實作環形隊列

既然是環形隊列,我們需要對是否空,是否滿,添加、取出資料進行從新整理

1. 判斷隊列是否滿了

當隊列資料存滿的時候,front與rear的正序查距離應該是queueSize - 1;此處不了解% queueSize,可以用筆将數組頭尾相連畫出來,用幾個數試試就知道了。

public Boolean isFull(){
	return front == (rear + 1) % queueSize;
}
           

3. 判斷隊列是否為空

隊列為空的時候就是隊列頭等于隊列尾的下标

public Boolean isEmpty(){
	return front == rear;
}
           

4. 實作隊列的添加資料到末尾

每添加一個資料,rear就要往後移一位,将資料放到rear裡。

public void addData(int data){
    if(!isFull()){
        rear = (rear + 1) % queueSize;
        array[rear] =data;
    }else {
        System.out.println("隊列已經爆滿了!!");
    }
}
           

5. 實作隊列的取出資料

public void getData(){
    if(!isEmpty()){
        front = (front + 1) % queueSize;
        System.out.println("取出的資料為:" +  array[front]);
        array[front] = 0;
    }else {
        System.out.println("隊列為空");
    }
}
           

6. 周遊數列

public void list(){
    if (isEmpty()){
        System.out.println("隊列是空的");
    }
    for (int i = front; i <= queueSize; i++) {
        System.out.print(array[i% queueSize] + " ");
    }
    System.out.println();
}
           

整體代碼如下:

package chengquan.dataStru;

public class MyQueue {
    private int front;  // 隊首
    private int rear;   // 隊尾
    private int queueSize; // 隊列長度
    private int[] array;
    public MyQueue(){

    }

    public MyQueue(int queueSize){
        // 剛執行個體化一個隊列的時候,隊裡沒有元素,
        this.front = 0;
        this.rear = 0;
        this.queueSize = queueSize;
        this.array = new int[queueSize];
    }
    /*
    判斷隊列是否為空
     */
    public Boolean isEmpty(){
        return front == rear;
    }

    /*
   判斷隊列是滿了
    */
    public Boolean isFull(){
        return front == (rear + 1) % queueSize;
    }
    /*
    實作功能:向隊列中添加一個元素
     */
    public void addData(int data){
        if(!isFull()){
            array[rear] =data;
            rear = (rear + 1) % queueSize;
        }else {
            System.out.println("隊列已經爆滿了!!");
        }
    }

    /*
    實作功能:從隊列中取出一個元素
     */
    public void getData(){
        if(!isEmpty()){
            System.out.println("取出的資料為:" +  array[front]);
            array[front] = 0;
            front = (front + 1) % queueSize;

        }else {
            System.out.println("隊列為空");
        }
    }

    /*
    周遊
     */
    public void list(){
        if (isEmpty()){
            System.out.println("隊列是空的");
        }else {
            for (int i = front; i < queueSize; i++) {
                if ((i % queueSize) == rear){
                    break;
                }
                System.out.print(array[i % queueSize] + " ");


            }
            System.out.println();
        }
    }

}

           

測試一下:

在這裡插入代碼片
           

繼續閱讀