Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.05.02;
Скачать: [xml.tar.bz2];

Вниз

Tree Walker: Create   Найти похожие ветки 

 
Satirus   (2002-04-19 17:14) [0]

Вопрос к умудрённым опытом в использовании компонента TTreeView.
Предложите оригинальный код для перебора веток дерева снаружи внутрь. То есть, как пройтись сначала по сиблингам корня, потом по их детям, потом по сиблингам детей и т. д., до последнего колена в глубину


 
Дмитрий Баранов   (2002-04-19 17:44) [1]

В цикле по всем узлам (0..TreeView1.Items.Count-1) строим массив массивов (динамических) указателей (TTreeNode).
Первый индекс - Items[i].Level, второй - порядковый номер узла в массиве.
Вариации на тему - не массивы, а стеки (динамический массив - тормоз).

Выстроили - работаем.


 
vuk   (2002-04-19 17:45) [2]

Рекурсивно. То есть пишется процедура, поторой на вход подается узел и она сначала проходит по всем его дочерним узлам а потом делает второй проход по ним же и вызывает сама себя, передавая каждый из дочерних узлов в качестве параметра.


 
vuk   (2002-04-19 17:46) [3]

Рекурсивно. То есть пишется процедура, которой на вход подается узел и она сначала проходит по всем его дочерним узлам а потом делает второй проход по ним же и вызывает сама себя, передавая каждый из дочерних узлов в качестве параметра.


 
MBo   (2002-04-19 17:48) [4]

если не хранить номера узлов, имеющих деток, то придется обходить все, проверяя level, т.е. сначала с level 0, потом с 1 ,и т.д., пока не будет таких 0.
А можно создавать при первом обходе список, сортированный по level и дальше по нему.


 
vuk   (2002-04-19 17:55) [5]

А чем рекурсия не устраивает?


 
Satirus   (2002-04-19 17:58) [6]

Дмитрий Баранов-> можно по подробней? Идея динамического массива у меня возникла сразу... Развейте её, пожалуйста, в виде кода


 
Дмитрий Баранов   (2002-04-19 18:10) [7]

Вот с удовольствием бы, только времени нет. Динамический массив как он реализован в Delphi я бы применять не стал, а взял бы аналог С++ map. В Delphi придется извращаться -
Type TArrNode = array of TTreeNode;
Type TTree = array of TArrNode;
(с array of array шибко нечитаемый код получается),
а затем везде впихивать SetLength.
Если это не очень срочно, то могу на выходных подумать.


 
vuk   (2002-04-19 18:12) [8]

Понял свою лажу. Извиняюсь.


 
Satirus   (2002-04-19 18:17) [9]

vuk-> Меня устраивает рекурсия, но я не знаю, с какой стороны к ней подойти. Можно примерный кусочек кода?
Заранее благодарен


 
Дмитрий Баранов   (2002-04-19 18:24) [10]

На коленках - рекурсия.

procedure Recurse(const Node: TTreeNode);
var i: integer;
begin
ShowMessage(Node.Text);
if not Node.HasChildren then exit
else
begin
for i:=0 to Node.Count-1 do
begin
Recurse(Node.Item[i]);
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Node: TTreeNode;
begin
Node:=TreeView1.Items[0];
Recurse(Node);
end;


 
MBo   (2002-04-19 18:25) [11]

procedure TForm1.Button1Click(Sender: TObject);
var sl,sl2:TStringlist;
i,j,k:integer;
begin
sl:=tstringlist.create;
sl2:=tstringlist.create;
for i:=0 to tv1.Items.count-1 do begin
j:=tv1.items[i].level-sl.count+1;
if j>0 then
for k:=1 to j do sl.add("");
sl[tv1.items[i].Level]:=sl[tv1.items[i].Level]+inttostr(i)+" ";
end;
for i:=0 to sl.count-1 do begin
memo1.lines.add("Level "+inttostr(i));
sl2.commatext:=sl[i];
for j:=0 to sl2.count-1 do
memo1.lines.add(tv1.items[strtoint(sl2[j])].text);
end;
sl.free;
sl2.free;
end;


 
Дмитрий Баранов   (2002-04-19 18:30) [12]

>> MBo © (19.04.02 18:25)
Тоже на коленках :) ?
Меня, например удивляет, почему в Delphi встроеных хэшей и мапов нет :)) StringList - это не выход :)) Это слишком просто и медленно :))


 
vuk   (2002-04-19 18:32) [13]

Рекурсия не пойдет. Я немного не верно понял задачу. Нормальным решением рекурсия будет только тогда, когда нужен проход в таком порядке: сначала корень, потом его первый дочерний узел, и т.д. в глубь, т.е. каждая ветка проходится до конца перед тем как будет пройдена другая ветка. У Вас же условие другое - перебор должен идти по уровням, а не по веткам.


 
Satirus   (2002-04-19 18:56) [14]

vuk-> Ну да. Мне надо пройтись по уровням


 
MBo   (2002-04-19 19:22) [15]

>StringList - это не выход :))
это демонстрация подхода, но вполне рабочий вариант

>Это слишком просто и медленно :))
все зависит от диаметры иглы - количества items


 
Satirus   (2002-04-19 21:01) [16]

>>vuk Возвращаясь к вопросу использования библиотеки XDOM, хочу спросить Вас, не использовали ли Вы её встроенный TDOMTreeWalker, подобие которого я и пытаюсь создать, но в облегченном варианте. Целевым объектом триволкера является всё тот же XML-file, но вот незадача, не могу его побороть! Может у Вас найдется пару простеньких примерчиков по вытягиванию древа из XML-file?
Буду очень признателен.


 
vuk   (2002-04-19 21:10) [17]

Дерево-то проще всего вытягивать рекурсивно, а не по уровням. Все достаточно прозрачно получается. В составе XDOM даже пример имеется как это сделать.
имя файла:
\example03\example03main.pas

Метод:
procedure TMainpage.UpdateTreeView(const doc: TdomDocument);


 
Satirus   (2002-04-19 21:32) [18]

>>vuk Этот пример я разбирал первым делом. Но там один недостаток: ветки названы по типу, а не по имени элемента, к тому же сложно вытянуть атрибуты каждой ветки...


 
vuk   (2002-04-19 21:38) [19]

Ну и какие проблемы? Переписать создание узлов - и все дела. А как атрибуты вытягивать - я Вам уже писал.


 
Набережных С.   (2002-04-19 22:43) [20]

Пример с массивом:

type
TArr = array of array of TTreeNode;

procedure Parse(TV: TTreeView; var A: TArr);
var
n,m,k:integer;
begin
m:=0; n:=0;
while n < TV.Items.Count do
with TV.Items[n] do
begin
if Level >= m then
begin
m:=Level + 1;
SetLength(A,m);
end;
k:=Length(A[Level]);
SetLength(A[Level],k+1);
A[level,k]:=TV.Items[n];
Inc(n);
end;
end;

Пример вызова:

var
Arr:TArr;

Parse(TreeView1,Arr);
for n:= 0 to Pred(Length(Arr)) do
begin
for m:=0 to Pred(Length(Arr[n]))do
Memo1.Lines.Add(StringOfChar(" ",Arr[n,m].Level*4)+Arr[n,m].Text);
end;


 
Satirus   (2002-04-20 19:05) [21]

>>Набережных С. Ваш пример выдает ошибку Undeclared identifier "Items"


 
Набережных С.   (2002-04-20 19:29) [22]


> Satirus © (20.04.02 19:05)

У меня на D5 не выдает. Возможно, в D6 изменили TTreeView, но тут я помочь не смогу. А ты никаких изменений не вносил? Покажи на всякий случай свой код.


 
Satirus   (2002-04-20 20:04) [23]

>>Набережных С. Я его отправил Вам на мыло


 
Набережных С.   (2002-04-20 20:43) [24]

Письмо получил. Дело в том, что строка
Nodes[level,ChildCount]:=TreeView.Items[NodeCount];
стоит внутри блока with и у TTreeNode есть свойство TreeView: TCustomTreeView, а у TCustomTreeView свойство Items не опубликовано. Измени имя параметра TreeView и все будет нормально.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.05.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.006 c
3-2452
XCB
2002-04-10 09:35
2002.05.02
Ora-03114


7-2701
ATLANTIDO
2002-02-07 20:53
2002.05.02
ОПЕРАЦИОНКА


3-2469
Yuraz
2002-04-11 08:16
2002.05.02
Когда удаляешь запись в DBGrid, DBGrid выделяет все строки


1-2560
Коля
2002-04-19 01:33
2002.05.02
Что это с иконкой?


3-2449
Yakudza
2002-04-10 15:31
2002.05.02
RecordCount





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский