Форум: "Основная";
Текущий архив: 2003.12.30;
Скачать: [xml.tar.bz2];
ВнизОрганизация дерева Найти похожие ветки
← →
Tuzemec (2003-12-16 09:37) [0]Как оргинизовать дерево я придумал,
Вопрос стал с удалением узла (и подузлов), у кого какие соображения будут?
Ктонибудь такую структуру организовывал раньше?
Что можно добавить (с чем я столкнусь ещё)?
Вот небольшой исходник
Type tree= ^Ttree;
Ttree = record
str1 : String [254];
lev : integer; //уровень дерева
flag : boolean; // пока ещё не придумал
level_up : tree; //на уровень вверх к корню дерева
level_down : tree; //на уровень вниз к вершине дерева
prev,
next : tree; //next item of chain
end;
VAR
root_tree,
cure_branch1, cure_branch2, cure_branch3 : tree;
int1 : integer=0;
Procedure init_tree;
begin //Procedure init_tree;
new (cure_branch1);
cure_branch2:=cure_branch1;
root_tree:=cure_branch1;
root_tree^.prev:=nil;
root_tree^.next:=nil; //по аналогии с цеопчками
cure_branch1.lev:=int1;// (:=0) так как всё таки корень дерева
end; //Procedure init_tree;
Procedure Init_branch;
begin
inc (int1);
new(cure_branch1);
cure_branch1^.level_up:=cure_branch2; //указываем на коренную ветку
cure_branch2^.level_down:=cure_branch1;//коренная ветка (корень)может указывать на ветки
{ не только корень может указывать на ветки, но и
ветки могут указывать на корень
Вернее будет сказать, что корень не в состоянии указывать на все ветки,
зато каздая ветка (ответвление) способно указывать на корень
}
cure_branch2:=cure_branch1; // просто для порядка
cure_branch1^.lev:=int1;
cure_branch1^.prev:=nil;
cure_branch1^.next:=nil;
end;
Procedure add_to_end; //=======================
begin //=======================
new (cure_branch1); //новый элемент
cure_branch1.level_up:=cure_branch2.level_up; //у обеих один предок
cure_branch1^.lev:=cure_branch2^.lev; //Оба элемента одного уровня
cure_branch2^.next:=cure_branch1; //связи между элемементами
cure_branch1^.prev:=cure_branch2; //одного уровня
cure_branch1^.next:=nil; //следующего элемента пока ещё
// конечно нет
// Оба указателя указывают на элементы
// одного уровня
cure_branch2:=cure_branch1; // Оба указателя указывают на один
// и тот же элемент
end; //====================================================================
Procedure add_to_beg; //=======================
begin //=======================
new (cure_branch1); //новый элемент
cure_branch1.level_up:=cure_branch2.level_up; //у обеих один предок
cure_branch1^.lev:=cure_branch2^.lev; //Оба элемента одного уровня
cure_branch2^.prev:=cure_branch1; //связи между элемементами
cure_branch1^.next:=cure_branch2; //одного уровня
cure_branch1^.prev:=nil; //Предыдущего элемента пока ещё
// конечно нет
// Оба указателя указывают на элементы
// одного уровня
cure_branch2:=cure_branch1; // Оба указателя указывают на один
// и тот же элемент
end; //====================================================================
//==========================================================================
//==========================================================================
//==========================================================================
//==========================================================================
Procedure del_from_end;
begin
{ На самом деле не всё так просто, последний элемент цепочки может быть
корневым для одной из веток, а потому чтобы освободить память полностью
необходимо удалить всю ветку
Для начала необходимо проверить есть ли уровни ниже последнего элемента
если есть, то вначале удалить то, что находится ниже, и только потом
удалять сам элемент.
}
//Двигаемся к концу цепочки
while cure_branch1^.next = nil do cure_branch1:=cure_branch1^.next;
//=======================
cure_branch2:=cure_branch1^.prev; //Второй указатель указывает на предпоследний элемент цепочки
//Далее изолируем элемент,,, во избежание ошибок
cure_branch1^.next:=nil; cure_branch1^.prev:=nil; cure_branch1.level_up:=nil;
if cure_branch1.level_down=nil // в этом случае всё просто (просто удаляем элемент)
then begin // cure_branch1.level_down=nil
Dispose (cure_branch1);
cure_branch1:=cure_branch2;// Оба указателя указывают на один
// и тот же элемент
end // cure_branch1.level_down=nil
else begin // cure_branch1.level_down<>nil
{
Позже опишу этот фрагмент программы отдельной процедурой, которую буду просто использовать
для удаления поддерева
}
//Движемся к самому "нижнему" листочку и удаляем его
cure_branch3:=cure_branch1; //Сохраняем указатель на текущий элемент,
//который и надо удалить
repeat cure_branch1:=cure_branch1^.level_down;
until cure_branch1^.level_down=nil;
if (cure_branch1^.next=nil) and (cure_branch1^.prev=nil)
then begin //С обоих сторон нижнего элемента ничего нет
cure_branch1:=cure_branch1^.level_up;
Dispose (cure_branch1^.level_down);
{ Возможна утечка памяти далее нужно будет проконтролировать этот момент (во время отладки) }
end //С обоих сторон нижнего элемента ничего нет
else begin //C одной из сторон чегонибудь нашлось
if cure_branch1^.next<>nil then
end; //C одной из сторон чегонибудь нашлось
end; // cure_branch1.level_down<>nil
//=======================
end; //====================================================================
Procedure del_from_beg;
begin
//=======================
//=======================
end; //====================================================================
//==========================================================================
//==========================================================================
//==========================================================================
//==========================================================================
end.
← →
Digitman (2003-12-16 10:29) [1]ну ты и загнууул)
чем стандартный TCustomTreeView не устроил тебя ?
там же все уже готово для любых "деревянных" задач !
← →
Юрий Федоров (2003-12-16 10:33) [2]Ну не знаю, я деревья организовываю по другому :
type
TMyTreeNodeObject = class
private
FList: TList; {В нем указатели на TMyTreeNodeObject}
...
end;
Вроде как попроще немного ))
← →
Tuzemec (2003-12-16 10:34) [3]Не доверяю я стандартным компонентам, к томуже я не всегда использую VCL.
Как его запихнуть в консольное приложение??????
← →
pasha_golub (2003-12-16 10:34) [4]Согласен с Юрием, абсолютно.
← →
Рамиль (2003-12-16 10:40) [5]Помоему неживая структура, обречена на умирание. А нельзя сделать в БД?
← →
Digitman (2003-12-16 10:49) [6]
> Не доверяю я стандартным компонентам
вот это как раз - зря... не доверять следует сторонним компонентам, особенно - без исх.текстов.. станд. же компоненты в подавляющем большинстве случаев имеют исходники, и этим все сказано
> к томуже я не всегда использую VCL
да на здоровье ! изолируйся от VCL, скопировав нужные фрагменты исх.текста компонента в свой автономный модуль и пользуй его)
> Как его запихнуть в консольное приложение
"запихнуть" - никак
а вот использовать - да точно так же как в GUI
← →
Erik (2003-12-16 10:50) [7]А почему масив неиспользовать? А всегда его использую и беды незная с любыми компонентами. Гланое это указатель на родителя(ParentInd), если -1 то нет родителя. В ParentInd записан индекс родительского элемента.
procedure TDevices.FillChildren(curNode: PVirtualNode);
var
i: Integer;
Data: ^RLink;
begin
if curNode = TreeRoot then
begin
for i := 0 to Length(ptrSeadmed^) - 1 do
with ptrSeadmed^[i] do
if (ParentID = -1) and ((Lopp = 0) or fViewAll) and (State <> stDelete)
then
FillChildren(InternalAdd(curNode, i))
end
else
for i := 0 to Length(ptrSeadmed^) - 1 do
with ptrSeadmed^[i] do
begin
Data := Tree.GetNodeData(curNode);
if (ParentID = Data.Index) and ((Lopp = 0) or fViewAll) and (State <>
stDelete) then
FillChildren(InternalAdd(curNode, i));
end;
end;
Это для TVirtualStringTree но подойдет для любого компонента. Главное index масива запомнить.
← →
REA (2003-12-16 10:54) [8]TMyTreeNode = Class(TObjectList)
End;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.12.30;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c