How to implement GetLastNode for TTreeNodes?

When I need to find the first node in TTreeView, I call TTreeNodes.GetFirstNode. However, sometimes I need to find the last node in the tree and there is no corresponding function TTreeNodes.GetLastNode.

I do not want to use Items[Count-1], as this leads to the fact that the whole tree passes through Result := Result.GetNext. Naturally, this only matters if there are many nodes in the tree views. I fully understand the virtues of virtual container controls, but so far I'm not going to switch to Virtual TreeView.

So far I have come up with the following:

function TTreeNodes.GetLastNode: TTreeNode;
var
  Node: TTreeNode;
begin
  Result := GetFirstNode;
  if not Assigned(Result) then begin
    exit;
  end;
  while True do begin
    Node := Result.GetNextSibling;
    if not Assigned(Node) then begin
      Node := Result.GetFirstChild;
      if not Assigned(Node) then begin
        exit;
      end;
    end;
    Result := Node;
  end;
end;

Can anyone:

  • Find a flaw in my logic?
  • Suggest improvements?

Change 1

. , , AV , , , - , . , , - , , .

+3
3

, - , , , , .

, , , - () node, Exit :

function TTreeNodes.GetLastNode: TTreeNode;
var
  Node: TTreeNode;
begin
  Node := GetFirstNode;
  Result := Node;
  if Result <> nil then
    repeat
      Result := Node;
      if Node <> nil then
        Node := Result.GetNextSibling;
      if Node = nil then
        Node := Result.GetFirstChild;
    until Node = nil;
end;
+6

, , - TList, List.Add OnAddition List.Remove OnDeletion (OnRemove?). List.Count-1 ( ) .

- , , , Virtual Tree View: -)

+2

If I were to implement it, this would probably be my first project.

function TTreeNodes.GetLastNode: TTreeNode;
var
  Node: TTreeNode;
  function GetLastSibling(aNode : TTreeNode) : TTreeNode;
  begin
    if not Assigned(aNode) then
      EXIT(nil);
    repeat
      Result := aNode;
      aNode := Result.GetNextSibling;
    until not Assigned(aNode) ;
  end;
begin
  Node := GetFirstNode;
  if not Assigned(Node) then begin
    exit;
  end;

  repeat
    Result := GetLastSibling(Node);
    Node := Result.GetFirstChild;
  until not Assigned(Node);
end;

I find this a little readable. It might be a little slower though.

I'm not sure if this approach will be faster than the [Count-1] elements, in some cases it may be slower, since TTreeNodes actually caches the last node access via the items property.

+2
source

All Articles