【資料結構】佇列(Queue)介紹與使用
生活中的各種佇列
系統 | 客戶 | 服務者 |
---|---|---|
接待櫃台 | 一般人員 | 接待人員 |
購票櫃台(高鐵、台鐵、戲院…) | 購票者 | 售票服務人員 |
醫院 | 病患 | 護理師 |
機場 | 飛機 | 飛機跑道 |
道路網 | 汽車 | 交通號誌燈 |
超市、攤販 | 購買者 | 結帳櫃台 |
電腦 | 工作 | CPU, disk, printer |
Queue的種類
- Multiple queues, multiple servers,台鐵售票、量販店/統聯結帳櫃台
- Single queue, multiple servers,高鐵售票、
- Single queue, single server, 小型商店、攤販…
- Priority queues
C# Queue類別
C# System.Collection 命名空間裏提供了一個Queue類別,實現在佇列先進行出的概念(FIFO,First In First Out),和堆疊Stack 的操作(後進先出)完全不一樣。Queue類別也是一個有序集合物件。 Queue集合類別允許多個null/空值,且允許重複的值,提供Enqueue() 方法來加入值到Queue集合物件中,Dequeue() 方法從Queue集合物件中取出資料。Queue重要的屬性與方法
方法 或 屬性 | 用途 |
---|---|
Count | 傳回Queue集合物件中的元素數量 |
Enqueue | 加入一個項目到queue中 |
Dequeue | 從queue的前端取出一個項目並刪除該項目 |
Peek | 從queue的前端取出一個項目(不刪除該項目) |
Contains | 檢查queue是否包含某一個特定項目 |
Clear | 清除queue所有的項目 |
TrimToSize | 調整queue的大小到實際儲存項目的大小 |
加入項目到 Queue中:
Queue 是一個非泛型的集合(non-generic collection),你可以使用Enqueue()方法加入任何資料形態的元素到queue中。 Enqueue() 簽名: void Enqueue(object obj)Enqueue()範例
Queue queue = new Queue(); queue.Enqueue(3); queue.Enqueue(2); queue.Enqueue(1); queue.Enqueue("Four");存取Queue:
Dequeue() 方法從queue的前端取出一個項目並刪除該項目。 Dequeue() method signature: object Dequeue()Dequeue()範例
Queue queue = new Queue(); queue.Enqueue(3); queue.Enqueue(2); queue.Enqueue(1); queue.Enqueue("Four"); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); while (queue.Count > 0) Console.WriteLine(queue.Dequeue()); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); 輸出: Queue中的元素數量: 4 3 2 1 Four Queue中的元素數量: 0Peek():
從queue的前端取出一個項目(不刪除該項目),在一個空的queue喚用Peek() 和 Dequeue() 方法會導至一個執行時期的例外, "InvalidOperationException". Peek() 方法 Signature: object Peek();Peek()範例:
Queue queue = new Queue(); queue.Enqueue(3); queue.Enqueue(2); queue.Enqueue(1); queue.Enqueue("Four"); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); Console.WriteLine(queue.Peek()); Console.WriteLine(queue.Peek()); Console.WriteLine(queue.Peek()); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); 輸出: Queue中的元素數量: 4 3 3 3 Queue中的元素數量: 4 如果你想走訪queue中的每一個元素,又不想刪去其中的元素,可以將queue轉換為一個陣列:走訪Queue範例:
Queue queue = new Queue(); queue.Enqueue(3); queue.Enqueue(2); queue.Enqueue(1); queue.Enqueue("Four"); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); foreach (var i in queue.ToArray()) Console.WriteLine(i); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); 輸出: Queue中的元素數量: 4 3 2 1 Four Queue中的元素數量: 4-
Contains方法
Contains範例
Queue queue = new Queue(); queue.Enqueue(3); queue.Enqueue(2); queue.Enqueue(1); queue.Enqueue("Four"); queue.Contains(2); // true queue.Contains(100); //false-
Clear()方法:
Clear()範例:
Queue queue = new Queue(); queue.Enqueue(3); queue.Enqueue(2); queue.Enqueue(1); queue.Enqueue("Four"); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); queue.Clear(); Console.WriteLine("Queue中的元素數量: {0}", queue.Count); 輸出: Queue中的元素數量: 4 Queue中的元素數量: 0使用Queue類別的佇列建立操作示範:
using System; using System.Collections; class Program { static void Main(string[] args) { //建立一個看診佇列 Queue myQ = new Queue(); myQ.Enqueue("張三");//新增人員到看診佇列,也就是加入排隊… myQ.Enqueue("李四"); myQ.Enqueue("王五"); myQ.Enqueue("馬六"); // 列印看診佇列的數量和值 Console.WriteLine("候診的人數: {0}", myQ.Count); // 列印看診佇列中的所有值 Console.Write("目前候診的名單:"); PrintValues(myQ); // 列印佇列中的第一個元素,並移除 Console.WriteLine("進入診間的人:t{0}", myQ.Dequeue()); // 加入看診佇列 Console.WriteLine("蘇小小加入等待看診排隊…"); myQ.Enqueue("蘇小小"); // 列印看診佇列中的所有值 Console.Write("目前候診的名單:"); PrintValues(myQ); // 列印看診佇列中的第一個元素,並移除 Console.WriteLine("進入診間的人:t{0}", myQ.Dequeue()); // 列印看診佇列中的所有值 Console.Write("目前候診的名單:"); PrintValues(myQ); // 列印看診佇列中的第一個元素 Console.WriteLine("下一個要進入診間的人(查詢): t{0}", myQ.Peek()); // 列印看診佇列中的所有值 Console.Write("目前候診的名單:"); PrintValues(myQ); Console.ReadLine(); } public static void PrintValues(IEnumerable myCollection) { foreach (Object obj in myCollection) Console.Write(" {0}", obj); Console.WriteLine(); } } /* 程式的輸出 候診的人數: 4 目前候診的名單: 張三 李四 王五 馬六 進入診間的人: 張三 蘇小小加入等待看診排隊… 目前候診的名單: 李四 王五 馬六 蘇小小 進入診間的人: 李四 目前候診的名單: 王五 馬六 蘇小小 下一個要進入診間的人(查詢): 王五 目前候診的名單: 王五 馬六 蘇小小 */