Способов обхода дерева – огромное количество, я приведу здесь самые простые.
Обход всего дерева от начала до конца
1 2 3 4 5 6 7 8 |
... Node:=TreeView.Items.GetFirstNode; repeat // DoSomething with Tree for Example // Node.Text:='Was here during travesing'; Node:=Node.GetNext; until not Assigned(Node) ; ... |
Обход в глубину узла 1
1 2 3 4 5 6 7 8 |
Procedure TMainForm.WalkParentAndAllChildren (Node:TTreeNode); var i:integer; begin memo1.Lines.Add(Node.Text); for i := 0 to Node.Count-1 do WalkParentAndAllChildren(Node[i]); // Recurisively goes all children end; |
Данная процедура обходит родителя и всех детей – рекурсивно. Вот ссылка на сайт, где взял идею такого обхода.
Обход в глубину узла 2
Вспомогательная функция поиска родителя узла
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function TCheckBoxSelectionThread.FindParent(Node, ParentNode: TTreeNode): boolean; begin Result:=false; Repeat if Node=ParentNode then begin Result:=true; break; end; Node:=Node.Parent; Until not Assigned(Node); end; |
Непосредственно сам обход в глубину узла по всем потомкам
1 2 3 4 5 6 7 8 |
Node := TreeView.Selected; repeat // Do something with Node Node:=Node.GetNext; until not (Assigned(Node)) or not FindParent(Node,TreeView.Selected); |
Начинаем с родителя, берем первого ребенка, если у него есть дети ещё и так далее, пока очередной узел не покажет, что у него не находится заданный родитель.
Обход в глубину узла 3 (ныряние)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
... var VeryLastChild, CurrentNode:TTreeNode; begin CurrentNode:=TreeView.Selected; if not Assigned(CurrentNode) then exit; // Поиск самого самого самого последнего узла, начиная с текущего VeryLastChild:=CurrentNode; while (VeryLastChild.HasChildren) do begin VeryLastChild:=VeryLastChild.GetLastChild; //<<<Записываем результат end; //Если узел не содержит детей if not CurrentNode.HasChildren then begin //DoSomething end; //Обход поддеревьев - деревьев, содержащих детей //Если узел содержит детей if (CurrentNode.HasChildren) then begin while True do begin //DoSomething if (CurrentNode<>VeryLastChild) then CurrentNode:=CurrentNode.GetNext else break; end; // end; end; |