在 Delphi 中,建立一個泛型連結串列(LinkedList
)容器需要定義節點類和連結串列管理類,並確保它們都是泛型的,以便可以儲存任何型別的元素。以下是一個簡單的泛型連結串列實現,它包括節點類 TLinkedListNode<T>
和連結串列管理類 TLinkedList<T>
。這個實現支援從中間刪除元素。
unit Generic.LinkedList;
interface
uses
System.SysUtils, System.Generics.Collections;
type
// 節點類,泛型 T 表示節點儲存的資料型別
TLinkedListNode<T> = class
private
FData: T;
FNext: TLinkedListNode<T>;
public
constructor Create(const AData: T);
property Data: T read FData write FData;
property Next: TLinkedListNode<T> read FNext write FNext;
end;
// 連結串列類,泛型 T 表示連結串列儲存的資料型別
TLinkedList<T> = class
private
FHead: TLinkedListNode<T>;
FTail: TLinkedListNode<T>;
FCount: Integer;
function GetNodeAt(AIndex: Integer): TLinkedListNode<T>;
public
constructor Create;
destructor Destroy; override;
// 新增元素到連結串列末尾
procedure Add(const AData: T);
// 從連結串列中刪除指定索引處的元素
procedure Delete(AIndex: Integer);
// 獲取連結串列中元素的數量
function Count: Integer;
// 獲取或設定指定索引處的元素
property Items[AIndex: Integer]: T read GetNodeAt.Data write GetNodeAt.Data; default;
end;
implementation
{ TLinkedListNode<T> }
constructor TLinkedListNode<T>.Create(const AData: T);
begin
FData := AData;
FNext := nil;
end;
{ TLinkedList<T> }
constructor TLinkedList<T>.Create;
begin
FHead := nil;
FTail := nil;
FCount := 0;
end;
destructor TLinkedList<T>.Destroy;
var
Current, Temp: TLinkedListNode<T>;
begin
Current := FHead;
while Current <> nil do
begin
Temp := Current;
Current := Current.Next;
Temp.Free;
end;
inherited;
end;
procedure TLinkedList<T>.Add(const AData: T);
var
NewNode: TLinkedListNode<T>;
begin
NewNode := TLinkedListNode<T>.Create(AData);
if FTail <> nil then
begin
FTail.Next := NewNode;
end
else
begin
FHead := NewNode;
end;
FTail := NewNode;
Inc(FCount);
end;
procedure TLinkedList<T>.Delete(AIndex: Integer);
var
Current, Previous: TLinkedListNode<T>;
begin
if (AIndex < 0) or (AIndex >= FCount) then
raise Exception.Create('Index out of bounds');
Current := FHead;
if AIndex = 0 then
begin
FHead := Current.Next;
if FHead = nil then
FTail := nil;
Current.Free;
end
else
begin
Previous := nil;
while AIndex > 0 do
begin
Previous := Current;
Current := Current.Next;
Dec(AIndex);
end;
Previous.Next := Current.Next;
if Previous.Next = nil then
FTail := Previous;
Current.Free;
end;
Dec(FCount);
end;
function TLinkedList<T>.Count: Integer;
begin
Result := FCount;
end;
function TLinkedList<T>.GetNodeAt(AIndex: Integer): TLinkedListNode<T>;
var
Current: TLinkedListNode<T>;
I: Integer;
begin
if (AIndex < 0) or (AIndex >= FCount) then
raise Exception.Create('Index out of bounds');
Current := FHead;
for I := 0 to AIndex - 1 do
begin
Current := Current.Next;
end;
Result := Current;
end;
end.
這個實現包括了以下功能:
TLinkedListNode<T>
:表示連結串列中的一個節點,包含資料和指向下一個節點的指標。TLinkedList<T>
:表示連結串列本身,管理節點的新增、刪除和訪問。Add
方法:在連結串列末尾新增一個新元素。Delete
方法:從連結串列中刪除指定索引處的元素。如果索引是 0,則刪除頭節點;否則,遍歷連結串列找到要刪除的節點,並調整前一個節點的Next
指標。Count
方法:返回連結串列中元素的數量。Items
屬性:允許透過索引訪問連結串列中的元素。這是透過GetNodeAt
方法實現的,該方法根據索引返回對應的節點。
請注意,這個實現沒有處理併發訪問或執行緒安全問題。如果你需要在多執行緒環境中使用連結串列,請新增適當的同步機制。此外,這個連結串列是單向的,如果你需要雙向連結串列,可以相應地擴充套件節點類和連結串列類。