資料結構 二 佇列 對陣列的重複利用

2022-07-20 03:48:12 字數 3790 閱讀 3237

銀行叫號排隊的案例

佇列是乙個有序列表,可以用陣列鍊錶來實現。

遵循先入先出的原則。例如:銀行先叫號的人先於後叫號的人辦理業務。誰先叫號誰先辦理,誰後叫號誰後辦理。即:先進入佇列的資料先取出,後進入佇列的資料後取出

示意圖(使用陣列模擬佇列示意圖)

佇列本身是有序列表,若使用陣列的結構來儲存佇列的資料,則佇列陣列的宣告如上圖,其中, maxsize 為佇列最大容量。

佇列的輸出、輸入分別是從佇列的頭部和尾部來處理,因此需要兩個變數 front 和 rear 來記錄佇列前後端的位置。front 隨著資料的取出而改變,rear 隨著資料的輸入而改變。

front:指向佇列的頭部資料的前乙個位置

rear:指向佇列的尾部資料

當我們將資料存入佇列時稱為"addqueue",addqueue 有兩個步驟

① 將佇列的尾部指標往後移一位:rear + 1;

② 當rear == maxsize - 1;則佇列已滿,無法新增資料到佇列中。反之,arr[++rear] = value。注意,新增乙個資料只需要隊尾後移一位即可。

當我們將資料從佇列中取出時稱為"getqueue",getqueue 有兩個步驟

① 將佇列的頭部指標後移一位:front + 1;

② 當front == rear;則隊列為空,沒有資料可取,否則,返回arr[++front]

public class arrayqueuetest  catch (exception e)  

break;

case 'p':

try catch (exception e)

break;

case 'q':

scanner.close();

loop = false;

break;

default:

break;

}} } }

class arrayqueue

public boolean isfull()

public boolean isempty()

public void addqueue(int value)

arr[++rear] = value;

system.out.println("新增成功"); }

public int getqueue()

return arr[++front]; }

public void showqueue()

for(int i = 0; i < arr.length; i++)

system.out.println(); }

public void peek()

system.out.println(arr[front + 1]);

}}

針對上述陣列模擬佇列,在測試的時候發現,當佇列資料已滿時,無法新增資料,但是當取出乙個資料時,還是提示佇列已滿。

目前陣列模擬的佇列的只能使用一次,沒有達到復用的效果。

將這個陣列使用乙個演算法,改進成 "環形佇列":取模 %

> 注意

front:在陣列模擬環形佇列中指向陣列頭部的資料,初始值為0

rear:在陣列模擬環形佇列中執行尾部資料的後一位(跟資料模擬佇列有區別),因為希望空出乙個空間作為約定,初始值為0

陣列模擬佇列之所以不能復用的原因是因為,一旦 rear == maxsize - 1; 就判斷為佇列已滿,但是在資料新增滿之後,這個 rear 在陣列模擬佇列中就不會再發生改變,沒有形成乙個環形結構。

思路就是如何讓這個 rear 在滿了之後還能再回到起點重新來過(操場跑圈),就需要在rear == maxsize - 1之後,手動將 rear 的值值為 0;front 隨著佇列中資料的取出也會逐漸趨向於 maxsize - 1,所以也需要手動將 front 的值置為0,判斷佇列已滿的條件就是 rear 所處的位置的下乙個位置就是 front 所處的位置:即 rear + 1 = front;

手動將達到最大值置為0的思路理解起來較容易,實現起來較繁瑣。

首先判斷已滿的條件為(rear + 1) % maxsize == front;maxsize 為陣列的長度,而實際佇列儲存資料的個數為 maxsize - 1 個

這樣取模的原因,如果向後面這樣取,rear % maxsize == front;在還沒向佇列新增資料時,則等式成立,無法新增資料

判斷為空的條件:rear == front;

當我們如上述分析時,這時佇列中的有效資料個數為(rear + maxsize - front) % maxsize;

+maxsize 的原因,是因為,如果出現 rear 比 front 快一圈的情況(跑圈),rear - front 就會出現負數,與需求相悖。

public class circlearrayqueuetest  catch (exception e) 

break;

case 'p':

try catch (exception e)

break;

case 'q':

scanner.close();

loop = false;

break;

default:

break;

}} }

}class circlearrayqueue

public boolean isfull()

public boolean isempty()

public void addqueue(int value)

arr[rear] = value;

rear = (rear + 1) % maxsize; // 防止索引越界

} public int getqueue()

int value = arr[front];

front = (front + 1) % maxsize; // 防止索引越界

return value;

} public void showqueue()

for (int i = front; i < front + size(); i++)

} public int size()

public void peek()

system.out.println(arr[front]);

} public int getfront()

public int getrear()

}

資料結構(二) 佇列

一 佇列定義 佇列是限定在一端進行插入,另一端進行刪除特殊線性表。二 佇列基本操作 入隊出隊 三 佇列例題 1.例1 舞伴配對問題 分析 這一題是一道經典的取模運算,每一次將編號往前加一位,到達n就取模。include include include include int main return ...

資料結構 二 (佇列)

在模擬實現 佇列前應先簡單的了解先佇列的一些特點 佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端 front 進行刪除操作,而在表的後端 rear 進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。佇列最大...

演算法與資料結構 二 佇列

佇列也是一種線性的資料結構,它與鍊錶的區別在於鍊錶可以在任意位置進行插入刪除操作,而佇列只能在一端進行插入,另一端進行刪除。它對應於現實世界中的排隊模型。佇列有兩種常見的實現方式 基於列表的實現和基於陣列的實現 基於鍊錶的佇列,我們需要儲存兩個指標,乙個指向頭節點,乙個指向尾節點。這種佇列不存在佇列...