Generic Delphi Tree structure

A generic Tree structure made in Delphi is freely available at this GitHub repository:

https://github.com/davidberneda/GenericTree

See the readme at GitHub for details and updated documentation.

This small class allows creating hierarchical structures where each “node” is a small object (20 bytes plus your own data size), containing a property of your desired type.

For example, a Tree of string nodes:

var MyTree : TNode<String>;

MyTree.Data :='hello';

2 thoughts to “Generic Delphi Tree structure”

  1. Great work! Delphi needs comp.sci.algorithm and data structure implementations like this to continue its long standing use since the days of Borland. Great to see the strides Embarcadero has made with regard to multi-platform support and coders like yourself expanding the library of shared resources and code. Thank you for saving me the time of coding this and writing this by sharing it. I will follow your example and share code of mine on github to help other Delphi coders build extensive libraries.

    Yours truly a somewhat controversial personality,

    Brian Joseph Johns

    Shhhhh! Digital Media

  2. Thanks for your Generic Tree. I’ve made some useful additions. “GetNext” is particularly useful for iterating the tree.

    function TNode.IsRoot : boolean;
    begin
      result := assigned(self) and (self.Index = -1);
    end;
    
    function TNode.GetNextAncestor : TNode;
    var
      parent, child : TNode;
      t : integer;
    begin
      result := nil;
      if assigned(self) and not self.IsRoot then
       begin
         parent := self.Parent;
         if assigned(parent) then
          begin
            if self.index = pred(parent.Count) {no more siblings} then result := Parent.GetNextAncestor
            else result := parent[succ(self.index)];
          end;
       end
    end;
    
    function TNode.GetFirstChild : TNode;
    begin
      if assigned(self) and (self.Count > 0) then result := self[0]
      else result := nil;
    end;
    
    function TNode.GetNext : TNode;
    begin
      result := nil;
      if assigned(self) then
       begin
         result := self.GetFirstChild;   // Go down through the levels
         if result = nil then result := self.GetNextAncestor;   // Go back through the levels
       end;
    end;
    
    function TNode.GetNextSibling : TNode;
    var
      parent, child : TNode;
      t : integer;
    begin
      result := nil;
      if assigned(self) and not self.IsRoot then
       begin
         parent := self.Parent;
         if assigned(parent) then
          begin
            if self.index < pred(parent.Count) then result := parent[succ(self.index)];
          end;
       end
    end;
    
    function TNode.FullCount : int64;
    // Returns a count of all nodes below and including the start node
    begin
      result := 0;
      while assigned(self) do
       begin
         inc(result);
         self := self.GetNext;
       end;
    end;

Comments are closed.