堆疊 是「後進先出」 (LIFO, Last In First Out) 的資料結構。想像一疊盤子:最後放上去的盤子,最先被拿走。Delphi 2009 的 TStack<T> 提供泛型強型別支援,適用於:

| 方法/屬性 | 說明 | 備註 |
|---|---|---|
Push(item) | 壓入元素 (推入堆疊頂端) | 無回傳值 |
Pop | 彈出並移除堆疊頂端元素 | 回傳 T,空堆疊會拋出例外 |
Peek | 查看堆疊頂端元素不移除 | 回傳 T,空堆疊會拋出例外 |
Count | 目前元素總數 | 唯讀屬性 |
Clear | 清空堆疊 | 不釋放元素物件 (除非用 TObjectStack) |
ToArray | 轉為陣列 (頂端在前) | 回傳 TArray<T> |
type
TRec = record
Name: string;
Age: Word;
end;
var
Stack: TStack<TRec>;
procedure TForm1.FormCreate(Sender: TObject);
begin
Stack := TStack<TRec>.Create;
Memo1.Clear;
Button1.Caption := '壓棧';
Button2.Caption := '出棧';
Button3.Caption := '查看下一個出棧';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Stack.Free;
end;
// 壓棧
procedure TForm1.Button1Click(Sender: TObject);
var
rec: TRec;
begin
rec.Name := StringOfChar(Char(65 + Random(26)), 3); // 隨機 3 大寫字母
rec.Age := Random(150);
Stack.Push(rec);
Caption := Format('目前堆疊筆數: %d', [Stack.Count]);
Memo1.Lines.Add(Format('%s, %d', [rec.Name, rec.Age])); // 同步顯示
end;
// 出棧
procedure TForm1.Button2Click(Sender: TObject);
var
rec: TRec;
begin
if Stack.Count = 0 then Exit;
rec := Stack.Pop;
ShowMessage(Format('彈出: %s, %d', [rec.Name, rec.Age]));
Caption := Format('目前堆疊筆數: %d', [Stack.Count]);
Memo1.Lines.Delete(Memo1.Lines.Count - 1); // 移除最後一行 (對應堆疊頂端)
end;
// 查看頂端
procedure TForm1.Button3Click(Sender: TObject);
var
rec: TRec;
begin
if Stack.Count = 0 then Exit;
rec := Stack.Peek;
ShowMessage(Format('頂端元素: %s, %d', [rec.Name, rec.Age]));
end;
var
BackStack, ForwardStack: TStack<string>;
procedure NavigateTo(url: string);
begin
if CurrentUrl <> '' then BackStack.Push(CurrentUrl);
CurrentUrl := url;
ForwardStack.Clear; // 新導航清空前進歷史
end;
procedure GoBack;
begin
if BackStack.Count > 0 then
begin
ForwardStack.Push(CurrentUrl);
CurrentUrl := BackStack.Pop;
end;
end;
function CheckBrackets(const expr: string): Boolean;
var
stack: TStack<Char>;
c: Char;
begin
stack := TStack<Char>.Create;
try
for c in expr do
case c of
'(', '[', '{': stack.Push(c);
')': if (stack.Count = 0) or (stack.Pop <> '(') then Exit(False);
']': if (stack.Count = 0) or (stack.Pop <> '[') then Exit(False);
'}': if (stack.Count = 0) or (stack.Pop <> '{') then Exit(False);
end;
Result := stack.Count = 0;
finally
stack.Free;
end;
end;
procedure DFS_NonRecursive(start: TTreeNode);
var
stack: TStack<TTreeNode>;
node: TTreeNode;
begin
stack := TStack<TTreeNode>.Create;
try
stack.Push(start);
while stack.Count > 0 do
begin
node := stack.Pop;
ProcessNode(node);
// 依序壓入子節點 (注意順序影響遍歷順序)
for var i := node.Count - 1 downto 0 do
stack.Push(node.Item[i]);
end;
finally
stack.Free;
end;
end;
TStack<T>.Create(Capacity) 預分配TStack<TRec> 存放值型別 (記錄),複製語意;TStack<TObj> 存放參考,需自行管理物件生命週期Count > 0TStack<T> 以泛型封裝經典 LIFO 結構,API 簡潔直觀,配合 Delphi 記錄型別支援,能高效解決回溯、歷史管理、語法分析等經典演算法問題,是演算法實作工具箱中的核心元件。