首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 2009 泛型佇列 TQueue<T> 完整教學:FIFO 資料結構實戰

     編輯:Delphi

佇列 (Queue) 基本觀念

佇列 是「先進先出」 (FIFO, First In First Out) 的資料結構。就像排隊買票:最先排隊的人,最先買到票離開。Delphi 2009 的 TQueue<T> 提供泛型強型別支援,適用於:

  • 訊息/工作排程系統
  • 廣度優先搜尋 (BFS)
  • 緩衝區/資料流處理
  • 生產者-消費者模式

執行效果動畫

核心 API 速查

方法/屬性說明備註
Enqueue(item)加入元素到佇列尾端無回傳值
Dequeue移除並回傳佇列前端元素回傳 T,空佇列會拋出例外
Peek查看佇列前端元素不移除回傳 T,空佇列會拋出例外
Count目前元素總數唯讀屬性
Clear清空佇列不釋放元素物件 (除非用 TObjectQueue)
ToArray轉為陣列 (前端在前)回傳 TArray<T>

完整實作範例:記錄資料佇列

資料結構定義


type
  TRec = record
    Name: string;
    Age: Word;
  end;

var
  Queue: TQueue<TRec>;

表單操作邏輯


procedure TForm1.FormCreate(Sender: TObject);
begin
  Queue := TQueue<TRec>.Create;
  Memo1.Clear;
  Button1.Caption := '入列';
  Button2.Caption := '出列';
  Button3.Caption := '查看下一個出列';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Queue.Free;
end;

// 入列
procedure TForm1.Button1Click(Sender: TObject);
var
  rec: TRec;
begin
  rec.Name := StringOfChar(Char(65 + Random(26)), 3);
  rec.Age := Random(150);
  Queue.Enqueue(rec);
  Caption := Format('目前佇列筆數: %d', [Queue.Count]);
  Memo1.Lines.Add(Format('%s, %d', [rec.Name, rec.Age])); // 同步顯示 (新增在最後)
end;

// 出列
procedure TForm1.Button2Click(Sender: TObject);
var
  rec: TRec;
begin
  if Queue.Count = 0 then Exit;
  rec := Queue.Dequeue;
  ShowMessage(Format('出列: %s, %d', [rec.Name, rec.Age]));
  Caption := Format('目前佇列筆數: %d', [Queue.Count]);
  Memo1.Lines.Delete(0); // 移除第一行 (對應佇列前端)
end;

// 查看前端
procedure TForm1.Button3Click(Sender: TObject);
var
  rec: TRec;
begin
  if Queue.Count = 0 then Exit;
  rec := Queue.Peek;
  ShowMessage(Format('前端元素: %s, %d', [rec.Name, rec.Age]));
end;

進階應用場景

1. 生產者-消費者模式 (單執行緒模擬)


var
  TaskQueue: TQueue<TTask>;

procedure Producer;
var i: Integer;
begin
  for i := 1 to 100 do
    TaskQueue.Enqueue(TTask.Create(i)); // 產生任務
end;

procedure Consumer;
var task: TTask;
begin
  while TaskQueue.Count > 0 do
  begin
    task := TaskQueue.Dequeue;
    try
      task.Execute;
    finally
      task.Free;
    end;
  end;
end;

2. 廣度優先搜尋 (BFS) 圖遍歷


procedure BFS(start: TGraphNode);
var
  queue: TQueue<TGraphNode>;
  node, neighbor: TGraphNode;
begin
  queue := TQueue<TGraphNode>.Create;
  try
    queue.Enqueue(start);
    start.Visited := True;
    while queue.Count > 0 do
    begin
      node := queue.Dequeue;
      ProcessNode(node);
      for neighbor in node.Neighbors do
        if not neighbor.Visited then
        begin
          neighbor.Visited := True;
          queue.Enqueue(neighbor);
        end;
    end;
  finally
    queue.Free;
  end;
end;

3. 固定大小循環緩衝區 (簡易版)


type
  TCircularBuffer<T> = class
  private
    FQueue: TQueue<T>;
    FMaxSize: Integer;
  public
    constructor Create(MaxSize: Integer);
    procedure Push(item: T);
    function Pop: T;
    property Count: Integer read FQueue.Count;
  end;

procedure TCircularBuffer<T>.Push(item: T);
begin
  if FQueue.Count = FMaxSize then FQueue.Dequeue; // 滿則移除最舊
  FQueue.Enqueue(item);
end;

TQueue vs TStack 行為對比

操作TQueue (FIFO)TStack (LIFO)
加入Enqueue (尾端)Push (頂端)
移除Dequeue (前端)Pop (頂端)
查看Peek (前端)Peek (頂端)
Memo 同步Delete(0) 移除首行Delete(Count-1) 移除尾行
典型用途排程、BFS、緩衝Undo、DFS、運算式求值

效能與注意事項

  • 環狀陣列實作:內部採用環狀緩衝區,Enqueue/Dequeue 皆為 O(1) 平攤時間
  • 預分配容量:TQueue<T>.Create(Capacity) 減少記憶體重新分配
  • 記錄型別優勢:TQueue<TRec> 避免物件管理負擔,適合高頻資料流
  • 執行緒安全:非安全,多執行緒需 TMonitor 或關鍵區段保護

總結

TQueue<T> 以泛型封裝高效能 FIFO 結構,配合環狀陣列實作與簡潔 API,是處理排程、遍歷、緩衝等循序資料流程的首選工具。掌握 Enqueue/Dequeue/Peek 三大核心操作,即可靈活應對各類佇列場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved