1、TList插入删除内存操作过于频繁,效率不高,可用以于链表替换
2、下链表实现自带了一个Node分配池,以避免内存分配的频率。
(包括:单线链表,双向链表,队列)
//链表节点
pTSingleLinkedNode = ^TSingleLinkedNode;
TSingleLinkedNode = record
private
Next: pTSingleLinkedNode;
public
Data: TObject;
end;
pTMyLinkedNode = ^TMyLinkedNode;
TMyLinkedNode = record
public
Data: TObject;
private
Prev, Next: pTMyLinkedNode;
end;
//链表池
TLinkedNodePool = class
protected
m_Nodes: array of Pointer;
m_Index: Integer;
m_Capacity: Integer;
m_Stoped: Boolean;
function NewNode: Pointer; virtual; abstract;
procedure DisposeNode(p: Pointer); virtual; abstract;
public
constructor Create(nCapacity: Integer = 512); virtual;
destructor Destroy; override;
function GetNode: Pointer;
procedure RetNode(p: Pointer);
procedure ReSize;
procedure Clear;
end;
//单向链表
TSingleLinkedBase = class(TLinkedNodePool)
protected
m_Head: pTSingleLinkedNode;
m_Curr: pTSingleLinkedNode;
m_Count: Integer;
function NewNode: Pointer; override;
procedure DisposeNode(p: Pointer); override;
procedure AddObject(Obj: TObject);
function DeleteObject(Obj: TObject): pTSingleLinkedNode;
public
constructor Create(nCapacity: Integer = 512); override;
destructor Destroy; override;
procedure Clear;
function First: pTSingleLinkedNode;
function Next: pTSingleLinkedNode;
property Count: Integer read m_Count;
end;
//单向对象链表
TSingleObjectLinked = class(TSingleLinkedBase)
public
procedure Add(Obj: TObject);
function Delete(Obj: TObject): pTSingleLinkedNode;
end;
//单向指针链表
TSinglePointerLinked = class(TSingleLinkedBase)
public
procedure Add(Ptr: Pointer);
function Delete(Ptr: Pointer): pTSingleLinkedNode;
end;
//双链表基类,删除比单链表更快
TMyLinkedBase = class(TLinkedNodePool)
protected
m_Head, m_Tail: pTMyLinkedNode;
m_Curr: pTMyLinkedNode;
m_Count: Integer;
function NewNode: Pointer; override;
procedure DisposeNode(p: Pointer); override;
procedure AddObject(Obj: TObject);
function DeleteObject(Obj: TObject): pTMyLinkedNode;
public
constructor Create(nCapacity: Integer = 512); override;
destructor Destroy; override;
function DeleteNode(var Node: pTMyLinkedNode): pTMyLinkedNode;
function First: pTMyLinkedNode;
function Next: pTMyLinkedNode;
procedure Clear;
property Count: Integer read m_Count;
end;
//双向对象链表
TMyObjectLinked = class(TMyLinkedBase)
public
procedure Add(Obj: TObject);
function Delete(Obj: TObject): pTMyLinkedNode;
end;
//双向指针链表
TMyPointerLinked = class(TMyLinkedBase)
public
procedure Add(Ptr: Pointer);
function Delete(Ptr: Pointer): pTMyLinkedNode;
end;
//队列
TMyQueueBase = class(TMyLinkedBase)
protected
procedure PushObject(Obj: TObject);
function PopObject: TObject;
end;
//对象队列
TMyObjectQueue = class(TMyQueueBase)
public
procedure Push(Obj: TObject);
function Pop: TObject;
end;
//指针队列
TMyPointerQueue = class(TMyQueueBase)
public
procedure Push(Ptr: Pointer);
function Pop: Pointer;
end;
{ TLinkedNodePool }
constructor TLinkedNodePool.Create(nCapacity: Integer);
begin
SetLength(m_Nodes, nCapacity);
m_Capacity := nCapacity;
m_Index := -1;
end;
destructor TLinkedNodePool.Destroy;
begin
m_Stoped := True;
Clear;
SetLength(m_Nodes, 0);
inherited;
end;
procedure TLinkedNodePool.Clear;
var
i: Integer;
begin
for i := 0 to m_Index do
DisposeNode(m_Nodes[i]);
end;
function TLinkedNodePool.GetNode: Pointer;
begin
Result := nil;
if m_Index < 0 then
ReSize;
if m_Index >= 0 then begin
Result := m_Nodes[m_Index];
Dec(m_Index);
end;
end;
procedure TLinkedNodePool.RetNode(p: Pointer);
begin
if (m_Index >= Length(m_Nodes) - 1) or m_Stoped then
DisposeNode(p)
else begin
Inc(m_Index);
m_Nodes[m_Index] := p;
end;
end;
procedure TLinkedNodePool.ReSize;
var
i: Integer;
node: Pointer;
begin
for i := 0 to (m_Capacity div 2) do begin
if m_Index >= Length(m_Nodes) - 1 then
m_Index := 0
else
Inc(m_Index);
node := Self.NewNode;
m_Nodes[m_Index] := node;
end;
end;
{ TSingleLinkedBase }
var
g_count: Integer;
constructor TSingleLinkedBase.Create(nCapacity: Integer);
begin
inherited Create(nCapacity);
end;
destructor TSingleLinkedBase.Destroy;
begin
Assert(g_count > 0);
Clear;
inherited;
Assert(g_count = 0);
end;
procedure TSingleLinkedBase.Clear;
var
Temp, Temp1: pTSingleLinkedNode;
begin
Temp := m_Head;
while Temp <> nil do begin
Temp1 := Temp;
Temp := Temp1.Next;
Self.RetNode(Temp1);
end;
m_Head := nil;
m_Count := 0;
end;
procedure TSingleLinkedBase.AddObject(Obj: TObject);
var
node: pTSingleLinkedNode;
begin
node := Self.GetNode;
node.Data := Obj;
node.Next := nil;
if m_Head = nil then
m_Head := node
else begin
node.Next := m_Head.Next;
m_Head.Next := node;
end;
Inc(m_Count);
end;
function TSingleLinkedBase.DeleteObject(Obj: TObject): pTSingleLinkedNode;
var
Temp, priNode: pTSingleLinkedNode;
begin
Temp := m_head;
priNode := nil; //记录上个节点
Result := nil;
while Temp <> nil do begin
if Temp.Data = Obj then begin
if priNode = nil then //删除头节点
begin
m_Head := Temp.Next;
m_Curr := Temp.Next; //保持链表的next指针
Result := Temp.Next;
Self.RetNode(Temp);
Dec(m_Count);
end
else begin
priNode.Next := Temp.Next; //删除非头节点
Result := Temp.Next;
m_Curr := Temp.Next;
Self.RetNode(Temp);
Dec(m_Count);
end;
Break;
end
else begin
priNode := Temp;
Temp := Temp.Next;
end;
end;
end;
function TSingleLinkedBase.First: pTSingleLinkedNode;
begin
m_Curr := m_Head;
Result := m_Curr;
end;
function TSingleLinkedBase.Next: pTSingleLinkedNode;
begin
m_Curr := m_Curr.Next;
Result := m_Curr;
end;
procedure TSingleLinkedBase.DisposeNode(p: Pointer);
begin
Dispose(pTSingleLinkedNode(p));
Dec(g_count);
end;
function TSingleLinkedBase.NewNode: Pointer;
var
node: pTSingleLinkedNode;
begin
New(node);
node.Data := nil;
node.Next := nil;
Result := node;
Inc(g_count);
end;
{ TSingleObjectLinked }
procedure TSingleObjectLinked.Add(Obj: TObject);
begin
inherited AddObject(Obj);
end;
function TSingleObjectLinked.Delete(Obj: TObject): pTSingleLinkedNode;
begin
Result := inherited DeleteObject(Obj);
end;
{ TSinglePointerLinked }
procedure TSinglePointerLinked.Add(Ptr: Pointer);
begin
inherited AddObject(TObject(Ptr));
end;
function TSinglePointerLinked.Delete(Ptr: Pointer): pTSingleLinkedNode;
begin
Result := inherited DeleteObject(TObject(Ptr));
end;
{ TMyLinkedBase }
constructor TMyLinkedBase.Create(nCapacity: Integer);
begin
inherited Create(nCapacity);
New(m_Head);
m_Head.Next := m_Tail;
m_Head.Prev := nil;
m_Head.Data := nil;
end;
destructor TMyLinkedBase.Destroy;
begin
Dispose(m_Head);
Clear;
inherited;
end;
procedure TMyLinkedBase.AddObject(Obj: TObject);
var
Node: pTMyLinkedNode;
begin
Node := Self.GetNode;
Node.Data := Obj;
if m_Head.Next = nil then begin
m_Head.Next := Node;
Node.Prev := m_Head;
Node.Next := nil;
m_Tail := Node;
end
else begin
m_Head.Next.Prev := Node;
Node.Next := m_Head.Next;
Node.Prev := m_Head;
m_Head.Next := Node;
end;
Inc(m_Count);
end;
procedure TMyLinkedBase.Clear;
var
Temp, Temp1: pTMyLinkedNode;
begin
Temp := m_Head.Next;
while Temp <> nil do begin
Temp1 := Temp;
Temp := Temp.Next;
Self.RetNode(Temp1);
end;
m_Tail := nil;
m_Head.Next := m_Tail;
m_Count := 0;
end;
//头插法
function TMyLinkedBase.NewNode: Pointer;
var
node: pTMyLinkedNode;
begin
New(node);
node.Data := nil;
node.Prev := nil;
node.Next := nil;
Result := node;
end;
procedure TMyLinkedBase.DisposeNode(p: Pointer);
begin
Dispose(pTMyLinkedNode(p));
end;
function TMyLinkedBase.First: pTMyLinkedNode;
begin
m_Curr := m_Head.Next;
Result := m_Curr;
end;
function TMyLinkedBase.Next: pTMyLinkedNode;
begin
Result := m_Curr.Next;
m_Curr := m_Curr.Next;
end;
function TMyLinkedBase.DeleteObject(Obj: TObject): pTMyLinkedNode;
var
Temp: pTMyLinkedNode;
begin
Temp := m_Head.Next;
Result := nil;
while Temp <> nil do begin
if Temp.Data = Obj then begin
Temp.Prev.Next := Temp.Next;
Result := Temp.Next;
m_Curr := Temp.Next;
if Temp.Next <> nil then
Temp.Next.Prev := Temp.Prev
else if Temp.Prev = m_Head then
m_Tail := nil
else
m_Tail := Temp.Prev;
Self.RetNode(Temp);
Dec(m_Count);
Break;
end
else
Temp := Temp.Next;
end;
end;
function TMyLinkedBase.DeleteNode(var Node: pTMyLinkedNode): pTMyLinkedNode;
begin
Result := Node.Next;
m_Curr := Node.Next;
Node.Prev.Next := Node.Next;
if Node.Next <> nil then
Node.Next.Prev := Node.Prev
else if Node.Prev = m_Head then
m_Tail := nil
else
m_Tail := Node.Prev;
Self.RetNode(Node);
Dec(m_Count);
end;
{ TMyObjectLinked }
procedure TMyObjectLinked.Add(Obj: TObject);
begin
inherited AddOBject(Obj);
end;
function TMyObjectLinked.Delete(Obj: TObject): pTMyLinkedNode;
begin
Result := inherited DeleteObject(Obj);
end;
{ TMyPointerLinked }
procedure TMyPointerLinked.Add(Ptr: Pointer);
begin
inherited AddObject(TObject(Ptr));
end;
function TMyPointerLinked.Delete(Ptr: Pointer): pTMyLinkedNode;
begin
Result := inherited DeleteObject(TObject(Ptr));
end;
{ TMyQueueBase }
function TMyQueueBase.PopObject: TObject;
var
Temp: pTMyLinkedNode;
begin
Temp := m_Head.Next;
Result := nil;
if Temp <> nil then begin
Result := Temp.Data;
m_Head.Next := Temp.Next;
Temp.Prev := m_Head;
if m_Head.Next = nil then
m_Tail := nil;
Self.RetNode(Temp);
m_Curr := m_Head.Next; //迭代器重置
end;
Dec(m_Count);
end;
procedure TMyQueueBase.PushObject(Obj: TObject);
var
Node: pTMyLinkedNode;
begin
Node := GetNode;
Node.Data := Obj;
if m_Tail = nil then begin
m_Tail := Node;
m_Tail.Next := nil;
m_Tail.Prev := m_Head;
m_Head.Next := m_Tail;
end
else begin
m_Tail.Next := Node;
Node.Prev := m_Tail;
Node.Next := nil;
m_Tail := Node;
end;
Inc(m_Count);
end;
{ TMyObjectQueue }
function TMyObjectQueue.Pop: TObject;
begin
Result := inherited PopObject;
end;
procedure TMyObjectQueue.Push(Obj: TObject);
begin
inherited PushObject(Obj);
end;
{ TMyPointerQueue }
function TMyPointerQueue.Pop: Pointer;
begin
Result := Pointer(inherited PopObject);
end;
procedure TMyPointerQueue.Push(Ptr: Pointer);
begin
inherited PushObject(TObject(Ptr));
end;