Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Обход дерева


Автор: aktuba 24.1.2007, 17:38
Совсем перестал соображать, поможете?
Задача такая. Есть заполненное дерево. Пример:

Исходное дерево:

+Узел1
|
+Узел2(!)
|     |
|     +Узел3(!)
|     |
|     +Узел4
|
+Узел5
|     |
|     +Узел6(!)
|
+Узел7(!)

На основе этого дерева необходимо получить следующее:

+Узел2(!)
|     |
|     +Узел3(!)
|
+Узел6
|
+Узел7(!)

Есть идеи?

Автор: voha 24.1.2007, 17:43
Рекурсия поможет

Автор: aktuba 24.1.2007, 17:49
voha, это я и сам знаю. Я не могу понять, как определять (или передавать) Parent добавляемого узла...

Автор: voha 24.1.2007, 18:04
TNode.Parent

AddChild

или давай подробней

Автор: aktuba 24.1.2007, 18:13
voha, посмотри внимательно верхний пример. Узел6 добавить необходимо, но Узел5 добавлять нельзя. Как определить в какой узел его теперь добавлять?

Автор: Bose 24.1.2007, 18:22
Цитата(aktuba @  24.1.2007,  18:13 Найти цитируемый пост)
 Как определить в какой узел его теперь добавлять?


тогда добавляй в Узел5.Parent 

или(уже не по примеру), если в Узел5.Parent нельзя, то в Узел5.Parent.Parent

p.s. на некорректно заданный вопрос нельзя получить корректный ответ smile 





Автор: voha 24.1.2007, 18:23
запоминать последний добавленный узел, если последний добавленный = nil, значит добавляем в корень, 
при переключении на следующий корневой Node в исходном дереве сбрасывать ссылку на последний добавленный узел

ну если опять не то, тогда сдаюсь smile

Автор: aktuba 24.1.2007, 19:05
Bose, и как определить в рекурсии это?

Цитата

на некорректно заданный вопрос нельзя получить корректный ответ smile 


Вопрос задан корректно, прочитан не корректно  smile 


voha, 

Цитата

запоминать последний добавленный узел, если последний добавленный = nil, значит добавляем в корень


Наверное не в корень, а в Parent Parent-а, если он вставлен и т.д. Но как узнать, вставлен или нет?


Автор: Bose 24.1.2007, 19:29
Цитата(aktuba @  24.1.2007,  19:05 Найти цитируемый пост)
Наверное не в корень, а в Parent Parent-а, если он вставлен и т.д. Но как узнать, вставлен или нет?


Очень просто:

Цитата

+Узел1
|
+Узел2(!)
|     |
|     +Узел3(!)
|     |
|     +Узел4
|
+Узел5
|     |
|     +Узел6(!)
|
+Узел7(!)

Проверяй, если у узла есть восклицательный знак (!) в скобках, значит он вставлен, если знака нет - значит не вставлен. smile 

Автор: aktuba 24.1.2007, 19:43
Bose, если не хочешь вникать в задачу - лучше не надо ничего писать, хорошо?

Для всех остальных, пояснение. Есть исходное заполненное дерево. Из этого дерева необходимо по определенному условию выбрать узлы и их копии добавить в новое дерево, с сохранением структуры исходного дерева. Т.е., для исходного дерева вида

+Узел1
|
+Узел2(!)
|     |
|     +Узел3(!)
|     |
|     +Узел4
|
+Узел5
|     |
|     +Узел6(!)
|           |
|           +Узел7(!)
|           |
|           +Узел8
|                 |
|                 +Узел9(!)
|
+Узел10(!)

необходимо получить новое дерево

+Узел2
|     |
|     +Узел3
|
+Узел6
|     |
|     +Узел7
|     |
|     +Узел9
|
+Узел10

Для тех, кто читает через строку, поясняю. (!) - это просто показываю, какие узлы подходят под условие.

Необходимо написать функцию, которая это делает. Кто поможет?

Автор: MetalFan 24.1.2007, 20:11
как я понял, тебе нужно собрать всех первых детей?
нет. все нечетные ноды?
опять нет.
лично я не вижу никакой закономерности в выборе нодов.
парт.задание автору - составить внятный алгоритм "фильтрации" нодов

Автор: aktuba 24.1.2007, 20:53
Цитата

парт.задание автору - составить внятный алгоритм "фильтрации" нодов


Всех нодов, для которых выполняется определенное условие. И поменяй стиль общения, ок?

P.S.: специально для Metalfan-a: добавить в новое дерево узлы, для которых выполняется одно из следующих условий:

1. присутствует дата окончания задания и сегодняшняя дата попадает в промежуток между началом задания и окончанием задания;
2. присутствует дата окончания задания, но сегодняшняя дата НЕ попадает в промежуток между началом задания и окончанием задания, и указан флаг переноса просроченных заданий;
3. отсутствует дата окончания и сегодняшняя дата = дате начала задания.

Легче стало?

Автор: MetalFan 24.1.2007, 21:07
aktuba, ты за своим стилем следи, ок? метод огрызания на всех тоже не очень хорош ;)
тут никто не понял, что тебе надо.
Цитата(aktuba @  24.1.2007,  20:53 Найти цитируемый пост)
для которых выполняется определенное условие

а вот про это в начале ни слова не было

Автор: aktuba 24.1.2007, 21:12
MetalFan, это не огрызания... 

Цитата

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


Вот это издевательство. Вместо того чтобы спросить то, что не ясно - подколы... И если отвечаешь на вопрос - будь добр посмотреть другие ответы и вопросы, а не только верхний...

Цитата

а вот про это в начале ни слова не было


А ты отвечаешь только на первый пост?

Автор: Bose 24.1.2007, 21:46
Цитата(aktuba @  24.1.2007,  19:43 Найти цитируемый пост)
Bose, если не хочешь вникать в задачу - лучше не надо ничего писать, хорошо?

Я хочу. Просто у меня не получалось понять =)

Вот пример в псевдокоде:

Код

procedure BuildCopy( aParentOriginal, aParentCopy:TVirtualNode)
var 
  tmpCurrentNode, aParentCopyNew:TVirtualNode;
begin
  for i:=0 to aParentOriginal.ChildNodeCount-1 do
  begin
     tmpCurrentNode:=aParentOriginal.Node[i];
     if  УсловиеВыполняется (tmpCurrentNode) then 
     begin
         aParentCopyNew:= GetCopyFromNode(tmpCurrentNode);
         aParentCopy.addchild(aParentCopyNew);
     end
     else
        aParentCopyNew:=aParentCopy;
     if tmpCurrentNode.childcount>0 then 
        BuildCopy(tmpCurrentNode, aParentCopyNew); 
  end;
end;


В VirtualTree узлы перебирются по-другому, к сожалению не помню точного синтаксиса, а вспоминать нет времени.  Просто замени цикл for..do обхода на правильный(с использованием GetFirst,GetNext).
Написать функцию
function GetCopyFromNode(aNode:TVirtualNode):TVirtualNode;
которая создаст экземпляр копии узла и вернёт указатель на него

Конечно это не готовый ответ, но надеюсь, что этот код придаст верное направление твоим размышлениям.

Добавлено @ 21:47 
p.s.  УсловиеВыполняется - функция, которая возварщает True, если для данного узла выполняются необходимые условия.

Автор: CatATonik 25.1.2007, 09:54
Чой-то все нервные такие smile 
aktuba у VirtualTree есть такой метод CopyTo называется, это то что тебе надо, а детали я думаю сам додумаешь  smile 

ЗЫ А вопрос и вправду не понятно был задан.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)