delphi 양방향 체인 테이블, 단방향 체인 테이블,Tlist 교체 가능, 삭제 효율 추가
10925 단어 Delphi
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;
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Delphi] TStringBuilder그리고 꼭 사용해야만 할까? 그림처럼 Heap 영역에 "Hello" 공간을 생성하고 포인팅을 한다. "Hello World" 공간을 새로 생성한 후 포인팅을 하게 된다. 결국 "Hello" 라는 String 객체가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.