| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 | unit CacheTree;// Base Tree Class,interfaceuses  Classes, Math;type  // 基础树类 -- 合并项目, 导入Excel等树以此树为基础  TCacheTree = class;  TCacheNode = class;  TCacheNodeList = class  private    FList: TList;    function GetCount: Integer;    function GetFirst: TCacheNode;    function GetItems(AIndex: Integer): TCacheNode;    function GetLast: TCacheNode;    procedure SetItems(AIndex: Integer; const Value: TCacheNode);  public    constructor Create;    destructor Destroy; override;    function Add(ANode: TCacheNode): Integer;    procedure Insert(AIndex: Integer; ANode: TCacheNode);    procedure Delete(AIndex: Integer);    function Remove(ANode: TCacheNode): Integer;    procedure Clear;    function IndexOf(ANode: TCacheNode): Integer;    property Count: Integer read GetCount;    property First: TCacheNode read GetFirst;    property Last: TCacheNode read GetLast;    property Items[AIndex: Integer]: TCacheNode read GetItems write SetItems; default;  end;  TCacheNode = class  private    FID: Integer;    FParent: TCacheNode;    FNextSibling: TCacheNode;    FPreSibling: TCacheNode;    FChildren: TCacheNodeList;    FCacheTree: TCacheTree;    function GetFirstChild: TCacheNode;    function GetLastChild: TCacheNode;    function GetNextSiblingID: Integer;    function GetParentID: Integer;    function GetPreSiblingID: Integer;    function GetNodeID(ANode: TCacheNode): Integer;  public    constructor Create(ACacheTree: TCacheTree; AID: Integer);    destructor Destroy; override;    procedure InsertChild(AChildNode: TCacheNode);    procedure InsertNextSibling(ANextSibling: TCacheNode);    procedure InsertPreSibling(APreSibling: TCacheNode);    procedure RemoveChild(AChildNode: TCacheNode);    procedure DeleteChild(AIndex: Integer);    procedure ClearChildren;    property ID: Integer read FID;    property ParentID: Integer read GetParentID;    property PreSiblingID: Integer read GetPreSiblingID;    property NextSiblingID: Integer read GetNextSiblingID;    property Parent: TCacheNode read FParent write FParent;    property NextSibling: TCacheNode read FNextSibling write FNextSibling;    property PreSibling: TCacheNode read FPreSibling write FPreSibling;    property FirstChild: TCacheNode read GetFirstChild;    property LastChild: TCacheNode read GetLastChild;    property Children: TCacheNodeList read FChildren;  end;  TCacheTree = class  private    FCacheNodes: TCacheNodeList;    FRoot: TCacheNode;    FNewNodeID: Integer;    function GetFirstNode: TCacheNode;    procedure SetNewNodeID(const Value: Integer);  protected    function GetNewNodeID: Integer;       function GetNewNode: TCacheNode; virtual;  public    constructor Create; virtual;    destructor Destroy; override;    function AddNode(AParent: TCacheNode; ANextSibling: TCacheNode = nil): TCacheNode;    procedure DeleteNode(ANode: TCacheNode);    procedure ClearTreeNodes;    property Root: TCacheNode read FRoot;    property FirstNode: TCacheNode read GetFirstNode;    property CacheNodes: TCacheNodeList read FCacheNodes;    property NewNodeID: Integer read FNewNodeID write SetNewNodeID;  end;implementation{ TCacheNodeList }function TCacheNodeList.Add(ANode: TCacheNode): Integer;begin  Result := FList.Add(ANode);end;procedure TCacheNodeList.Clear;begin  FList.Clear;end;constructor TCacheNodeList.Create;begin  FList := TList.Create;end;procedure TCacheNodeList.Delete(AIndex: Integer);begin  FList.Delete(AIndex);end;destructor TCacheNodeList.Destroy;begin  FList.Free;  inherited;end;function TCacheNodeList.GetCount: Integer;begin  Result := FList.Count;end;function TCacheNodeList.GetFirst: TCacheNode;begin  Result := TCacheNode(FList.First);end;function TCacheNodeList.IndexOf(ANode: TCacheNode): Integer;begin  Result := FList.IndexOf(ANode);end;function TCacheNodeList.GetItems(AIndex: Integer): TCacheNode;begin  Result := TCacheNode(FList.Items[AIndex]);end;function TCacheNodeList.GetLast: TCacheNode;begin  Result := TCacheNode(FList.Last);end;procedure TCacheNodeList.Insert(AIndex: Integer; ANode: TCacheNode);begin  FList.Insert(AIndex, ANode);end;function TCacheNodeList.Remove(ANode: TCacheNode): Integer;begin  Result := FList.Remove(ANode);end;procedure TCacheNodeList.SetItems(AIndex: Integer;  const Value: TCacheNode);begin  FList.Items[AIndex] := Value;end;{ TCacheNode }procedure TCacheNode.ClearChildren;var  I: Integer;begin  for I := 0 to FChildren.Count - 1 do  begin    FChildren[I].ClearChildren;    FChildren[I].Free;  end;  FChildren.Clear;end;constructor TCacheNode.Create(ACacheTree: TCacheTree; AID: Integer);begin  FChildren := TCacheNodeList.Create;  FCacheTree := ACacheTree;  FID := AID;end;procedure TCacheNode.DeleteChild(AIndex: Integer);begin  if (AIndex >= 0) and (AIndex < FChildren.Count) then    RemoveChild(FChildren[AIndex]);end;destructor TCacheNode.Destroy;begin  FChildren.Free;  inherited;end;function TCacheNode.GetFirstChild: TCacheNode;begin  if FChildren.Count > 0 then    Result := FChildren.First  else    Result := nil;end;function TCacheNode.GetLastChild: TCacheNode;begin  if FChildren.Count > 0 then    Result := FChildren.Last  else    Result := nil;end;function TCacheNode.GetNextSiblingID: Integer;begin  Result := GetNodeID(FNextSibling);end;function TCacheNode.GetNodeID(ANode: TCacheNode): Integer;begin  if Assigned(ANode) and (ANode <> nil) then    Result := ANode.ID  else    Result := -1;end;function TCacheNode.GetParentID: Integer;begin  Result := GetNodeID(FParent);end;function TCacheNode.GetPreSiblingID: Integer;begin  Result := GetNodeID(FPreSibling);end;procedure TCacheNode.InsertChild(AChildNode: TCacheNode);begin  AChildNode.FParent := Self;  AChildNode.FPreSibling := LastChild;  if LastChild <> nil then    LastChild.FNextSibling := AChildNode;  FChildren.Add(AChildNode);end;procedure TCacheNode.InsertNextSibling(ANextSibling: TCacheNode);begin  if Assigned(FNextSibling) then    FNextSibling.FPreSibling := ANextSibling;  ANextSibling.FNextSibling := FNextSibling;  FNextSibling := ANextSibling;  ANextSibling.FPreSibling := Self;  ANextSibling.FParent := FParent;  FParent.Children.Insert(FParent.Children.IndexOf(Self) + 1, ANextSibling);end;procedure TCacheNode.InsertPreSibling(APreSibling: TCacheNode);begin  if Assigned(FPreSibling) then    FPreSibling.FNextSibling := APreSibling;  APreSibling.FPreSibling := FPreSibling;  FPreSibling := APreSibling;  APreSibling.FNextSibling := Self;  APreSibling.FParent := FParent;  FParent.Children.Insert(FParent.Children.IndexOf(Self), APreSibling);end;procedure TCacheNode.RemoveChild(AChildNode: TCacheNode);begin  if AChildNode.FPreSibling <> nil then    AChildNode.FPreSibling.FNextSibling := AChildNode.FNextSibling;  if AChildNode.FNextSibling <> nil then    AChildNode.FNextSibling.FPreSibling := AChildNode.FPreSibling;  FChildren.Remove(AChildNode);end;{ TCacheTree }function TCacheTree.AddNode(AParent, ANextSibling: TCacheNode): TCacheNode;begin  Result := GetNewNode;  if Assigned(ANextSibling) then    ANextSibling.InsertPreSibling(Result)  else if Assigned(AParent) then    AParent.InsertChild(Result)  else    FRoot.InsertChild(Result);end;procedure TCacheTree.ClearTreeNodes;begin  FNewNodeID := 1;  FRoot.ClearChildren;  FCacheNodes.Clear;end;constructor TCacheTree.Create;begin  FCacheNodes := TCacheNodeList.Create;  FRoot := TCacheNode.Create(Self, -1);  FNewNodeID := 1;end;procedure TCacheTree.DeleteNode(ANode: TCacheNode);begin  ANode.FParent.RemoveChild(ANode);  ANode.ClearChildren;  FCacheNodes.Remove(ANode);  ANode.Free;end;destructor TCacheTree.Destroy;begin  ClearTreeNodes;  FRoot.Free;  FCacheNodes.Free;  inherited;end;function TCacheTree.GetFirstNode: TCacheNode;begin  if FCacheNodes.Count > 0 then    Result := FCacheNodes.First  else    Result := nil;end;function TCacheTree.GetNewNode: TCacheNode;begin  Result := TCacheNode.Create(Self, GetNewNodeID);  FCacheNodes.Add(Result);end;function TCacheTree.GetNewNodeID: Integer;begin  Result := FNewNodeID;  Inc(FNewNodeID);end;procedure TCacheTree.SetNewNodeID(const Value: Integer);begin  FNewNodeID := Max(FNewNodeID, Value);end;end.
 |