在 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
方法实现的,该方法根据索引返回对应的节点。
请注意,这个实现没有处理并发访问或线程安全问题。如果你需要在多线程环境中使用链表,请添加适当的同步机制。此外,这个链表是单向的,如果你需要双向链表,可以相应地扩展节点类和链表类。
本文来自博客园,作者:del88,转载请注明原文链接:https://www.cnblogs.com/del88/p/18595729
分类:
Delphi基础
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人