在 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
                    
                
                
            
        
浙公网安备 33010602011771号