1
0
mirror of synced 2024-12-22 01:03:07 +01:00

Added: integer tree (untested)

This commit is contained in:
Mark van Renswoude 2005-01-12 18:56:31 +00:00
parent 0fe601e3aa
commit 6e63ec4a9c

View File

@ -92,6 +92,7 @@ type
TX2BTCustomManager = class(TObject)
private
FCursor: TX2BTCustomCursor;
FDataSize: Cardinal;
protected
function GetCurrentKey(): Cardinal; virtual;
function GetEof(): Boolean; virtual;
@ -105,8 +106,8 @@ type
destructor Destroy(); override;
procedure Clear(); virtual; abstract;
procedure Insert(const AKey: Cardinal); virtual; abstract;
procedure Delete(const AKey: Cardinal); virtual; abstract;
function Insert(const AKey: Cardinal): Boolean; virtual; abstract;
function Delete(const AKey: Cardinal): Boolean; virtual; abstract;
function Exists(const AKey: Cardinal): Boolean; virtual; abstract;
function GetData(const AKey: Cardinal): Pointer; virtual; abstract;
@ -115,6 +116,7 @@ type
procedure Next(); virtual;
property CurrentKey: Cardinal read GetCurrentKey;
property DataSize: Cardinal read FDataSize write FDataSize;
property Eof: Boolean read GetEof;
end;
@ -125,8 +127,8 @@ type
*}
TX2BTDefaultManager = class(TX2BTCustomManager)
private
FRoot: PX2BTNode;
FLastNode: PX2BTNode;
FRoot: PX2BTNode;
protected
procedure CursorNeeded(); override;
procedure InvalidateCursor(); override;
@ -144,10 +146,12 @@ type
procedure AllocateNode(var ANode: PX2BTNode); virtual;
procedure DeallocateNode(var ANode: PX2BTNode); virtual;
function GetNodeSize(): Cardinal; virtual;
public
procedure Clear(); override;
procedure Insert(const AKey: Cardinal); override;
procedure Delete(const AKey: Cardinal); override;
function Insert(const AKey: Cardinal): Boolean; override;
function Delete(const AKey: Cardinal): Boolean; override;
function Exists(const AKey: Cardinal): Boolean; override;
function GetData(const AKey: Cardinal): Pointer; override;
@ -224,6 +228,24 @@ type
property Eof: Boolean read GetEof;
end;
{** Binary Tree with integer data.
*
* Extends the standard Binary Tree, allowing it to store an Integer value
* for each node in the tree.
*}
TX2IntegerTree = class(TX2BinaryTree)
private
function GetItem(const AKey: Cardinal): Integer;
procedure SetItem(const AKey: Cardinal; const Value: Integer);
function GetCurrentValue: Integer;
public
constructor Create(); override;
property CurrentValue: Integer read GetCurrentValue;
property Items[const AKey: Cardinal]: Integer read GetItem
write SetItem; default;
end;
implementation
resourcestring
RSBTKeyExists = 'The key "%d" already exists in the tree.';
@ -353,17 +375,26 @@ end;
Node Management
========================================}
procedure TX2BTDefaultManager.AllocateNode;
var
iSize: Cardinal;
begin
GetMem(ANode, SizeOf(TX2BTNode));
FillChar(ANode^, SizeOf(TX2BTNode), #0);
iSize := GetNodeSize() + FDataSize;
GetMem(ANode, iSize);
FillChar(ANode^, iSize, #0);
end;
procedure TX2BTDefaultManager.DeallocateNode;
begin
FreeMem(ANode, SizeOf(TX2BTNode));
FreeMem(ANode, GetNodeSize() + FDataSize);
ANode := nil;
end;
function TX2BTDefaultManager.GetNodeSize;
begin
Result := SizeOf(TX2BTNode);
end;
procedure TX2BTDefaultManager.Clear;
var
@ -511,16 +542,18 @@ begin
end;
procedure TX2BTDefaultManager.Insert;
function TX2BTDefaultManager.Insert;
var
pNode: PX2BTNode;
pParent: PX2BTNode;
begin
pNode := FindNode(AKey, pParent);
Result := False;
pNode := FindNode(AKey, pParent);
if Assigned(pNode) then
raise EBTKeyExists.CreateFmt(RSBTKeyExists, [AKey]);
exit;
Result := True;
InvalidateCursor();
AllocateNode(pNode);
FLastNode := pNode;
@ -540,16 +573,18 @@ begin
end;
end;
procedure TX2BTDefaultManager.Delete;
function TX2BTDefaultManager.Delete;
var
pNode: PX2BTNode;
pLowest: PX2BTNode;
begin
pNode := FindNodeOnly(AKey);
Result := False;
pNode := FindNodeOnly(AKey);
if not Assigned(pNode) then
raise EBTKeyNotFound.CreateFmt(RSBTKeyNotFound, [AKey]);
exit;
Result := True;
InvalidateCursor();
// If the node to be deleted has either one or no branch, it can simply be
@ -615,8 +650,15 @@ begin
end;
function TX2BTDefaultManager.GetData;
var
pNode: PX2BTNode;
begin
//! Implement GetData
pNode := FindNodeOnly(AKey);
if not Assigned(pNode) then
raise EBTKeyNotFound.CreateFmt(RSBTKeyNotFound, [AKey]);
Result := Pointer(Cardinal(pNode) + GetNodeSize());
end;
@ -666,12 +708,14 @@ end;
procedure TX2BinaryTree.Insert;
begin
FManager.Insert(AKey);
if not FManager.Insert(AKey) then
raise EBTKeyExists.CreateFmt(RSBTKeyExists, [AKey]);
end;
procedure TX2BinaryTree.Delete;
begin
FManager.Delete(AKey);
if not FManager.Delete(AKey) then
raise EBTKeyNotFound.CreateFmt(RSBTKeyNotFound, [AKey]);
end;
@ -702,4 +746,33 @@ begin
Result := FManager.Eof;
end;
{========================= TX2IntegerTree
Initialization
========================================}
constructor TX2IntegerTree.Create;
begin
inherited;
FManager.DataSize := SizeOf(Integer);
end;
function TX2IntegerTree.GetCurrentValue;
begin
Result := GetItem(FManager.CurrentKey);
end;
function TX2IntegerTree.GetItem;
begin
Result := PInteger(FManager.GetData(AKey))^;
end;
procedure TX2IntegerTree.SetItem;
begin
FManager.Insert(AKey);
PInteger(FManager.GetData(AKey))^ := Value;
end;
end.