Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.008 c
4-99821
System
2003-10-31 04:59
2003.12.30
Поменять иконку в EXE файле!?


1-99544
Jiurasdg45
2003-12-16 11:45
2003.12.30
Защита программ!!!


1-99592
h0use
2003-12-17 10:50
2003.12.30
Как в RichEdit Выводить строку с заданным стилем?


3-99453
Roman_kv
2003-12-05 15:58
2003.12.30
Как определить изменялись ли данные в гриде?


4-99824
Дмитрий Д
2003-11-01 09:08
2003.12.30
Notebooc





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский