![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
"Случайная" переменная?
markers © (2006-10-19 10:26:00)Можно-ли реализовать и как %subj ? Заренее Спасибо!
Сергей М. (2006-10-20 08:11:00) [1]
> Palladin
Идея со списком "беспризорников" мне понятна. Можно, конечно, и ее реализовать, только вот вопрос об эффективности такой реализации довольно серьезен. Можно опять же говорить о частном случае, когда "двухпроходная схема" на кл.стороне (второй проход - привязка "беспризорников") будет эффективней, чем формирование нужных НД сразу на серв.стороне.
markers (2006-10-20 01:11:00) [2]не сорьтесь из-за меня!
Та поправка что была мне, благополучно поменяло ситуацию :) И вообще ИМХО енто один из самых лучших способов построить дерево с детьми! Всё работает прекрасно даже лучше чем не рекурсивный мой вариант (в другом топике опобликован, основанный на поиске родителя).
Palladin (2006-10-19 18:39:00) [3]
> Наиль © (19.10.06 17:59) [55]
это да, это уже рекурсивное дерево, в этом случае структура данных меняется, банальная пара ключ - узел нервно курит в сторонке, а используются списки, и дети в контроле формируются динамически, а не махом... в случае рекурсии с точки зрения оптимизации скорости исполнения нужно использовать динамические запросы...
Palladin (2006-10-19 18:23:00) [4]правда под D6, если ее у тебя нет, то пришлю урезанные исходники dcu файлов
Palladin (2006-10-19 18:22:00) [5]
> Сергей М. ©
ты все еще продолжаешь неверить своим глазам? хорошо
http://tiravi.narod.ru/send1.zip
компилируй, исполняй, выставляй НД как твоей душе угодно...
Сергей М. (2006-10-19 18:03:00) [6]
> база выдаст кольцо. Т.е. каждый элемент ссылается на следующий,
> а последний на первый
Опять же - частный случай)
Рекурсия же с отдельным запросом по детям указанного конкретного родителя реализует именнго общийслучай.
Сергей М. (2006-10-19 18:01:00) [7]
> Нет ничего не возможного в том, чтобы загрузить нижний элемент,
> раньше верхнего
При ограниченных возможностях навигации по НД (тот самый частный случай) шансы получить запись n+i (i > 0) раньше записи n оставляют желать лучшего)
Palladin (2006-10-19 18:01:00) [8]блин!!!! тэг забыл закрыть... ладно, флудить не буду, если все таки трудно с восприятием жирного, скажи, подправлю...
Palladin (2006-10-19 18:00:00) [9]все комментировать не стал, только ключевые моменты
procedure TForm1.Button1Click(Sender: TObject);
Type
PItem=^TItem;
TItem=Record // описание записи для "безпризорника", дабы в TList ее хранить
nID:Integer;
strCaption:String;
End;
Var
theUnlinked, // безпризорники в виде
{
ID будущего родителя
данные безпризорника 1
данные безпризорника 2
как в твоем примере здесь будет содержатся
: +0
: | 1
или как в примере выше из четырех записей
: +0
: | 2
: | 3
}
theTree:TWRIntegerMap; // основные данные (ключ - значение): ID записи - созданный и уже существующий TTreeNode
q:TADOQuery;
n,nID,nIDParent:Integer;
strCaption:String;
// рекурсивная функция создания TTreeNode в TTreeView'е :)
Function _CreateNode(p_theParent:TTreeNode;p_nID:Integer;Const p_strCaption:String):TTreeNode;
Var
i,n:Integer;
Begin
// создали узел
Result:=TreeView.Items.AddChild(p_theParent,p_strCaption);
Result.Data:=Pointer(p_nID);
// ищем по своему ID в списке безпризорников
If theUnlinked.Find(p_nID,n) Then
Begin
// нашли нашего(наших) потерявшегося (шихся)
For i:=0 to TList(theUnlinked.ObjectData[n]).Count-1 Do
Begin
// добавляем каждого к себе в семью
With PItem(TList(theUnlinked.ObjectData[n])[i])^ Do
theTree.Add_Integer(nID,Integer( _CreateNode(Result,nID,strCaption)));
// удаляя запись о нем в детдоме
Dispose(PItem(TList(theUnlinked.ObjectData[n])[i]));
End;
End;
End;
// процедура регистрации безпризорника в детдоме
Procedure _AddToUnlinked(p_nID,p_nIDParent:Integer;Const p_strCaption:String);
Var
n:Integer;
p:PItem;
Begin
// создаем для него в регистратуре запись
New(p);
p.nID:=p_nID;
p.strCaption:=p_strCaption;
// ищем а были ли в роддоме его сородичи по родителям
If Not theUnlinked.Find(p_nIDParent,n) Then n:=theUnlinked.Add_Object(p_nIDParent,TList.Create); // не было, ничего страшного создаем новый список братьев и сестер
TList(theUnlinked.ObjectData[n]).Add(p); // добавляем его туда
End;
begin
theTree:=TWRIntegerMap.Create;
theUnlinked:=TWRIntegerMap.Create;
q:=TADOQuery.Create(Nil);
q.Connection:=ADOConnection1;
vtQuickADOQuery(q);
q.sql.text:='select id, id_parent, caption from tree order by caption';
q.Open;
While not q.Eof Do
Begin
nID:=q.Fields[0].AsInteger;
strCaption:=q.Fields[2].AsString;
If q.Fields[1].IsNull
Then theTree.Add_Integer(nID,Integer(_CreateNode(Nil,nID,strCaption))) // еси вдруг товарисч ничей не ребенок, пихаем его в корень
Else // иначе :)
Begin
nIDParent:=q.Fields[1].AsInteger;
// пытаемся в уже существующих семьях найти родителя
If theTree.Find(nIDParent,n)
Then theTree.Add_Integer(nID,Integer(_CreateNode(TTreeNode(theTree.IntegerData[n]),nI D,strCaption))) // нашли, отослали дитятко под его крыло
Else _AddToUnlinked(nID,nIDParent,strCaption); // а иначе - определили в детдом
End;
q.Next;
End;
q.Close;
q.Free;
theTree.Free;
theUnlinked.Free;
end;
надеюсь так понятней...
Наиль (2006-10-19 17:59:00) [10]Уверен, что в данном споре выиграет Palladin.
Нет ничего не возможного в том, чтобы загрузить нижний элемент, раньше верхнего.
Но спор пока вертиться вокруг дерьев.
Совсем другое дело, если база выдаст кольцо. Т.е. каждый элемент ссылается на следующий, а последний на первый.
Сергей М. (2006-10-19 17:53:00) [11]
> В результате тот же запрос вернет
Здесь - в предположении что индекс по перв.ключу при этом по каким-то причинам не использован, т.е. записи в рез. НД будут фигурировать в порядке их "физического" следования.
А если даже индекс по перв.ключу по умолчанию задействован, то ничто не мешает мне модифицировать исх.таблицу таким образом:
id, parent:
1 - 2
2 - Null
что тоже приведет к "краху" подобного алгоритма.
Palladin (2006-10-19 17:47:00) [12]нет не в виде двух узлов,
ладно: сейчас полностью откомментирую и запостю...
Сергей М. (2006-10-19 17:43:00) [13]
> Palladin © (19.10.06 17:34) [47]
вот смотри:
Было:
id, parent:
0 - Null
1 - 0
Запрос
select * from Treetable
вернет НД, по которому твой алгоритм построит совершенно корректное дерево, отражающее действительность.
Теперь я удалил запись с Id = 0 (почему я не вправе это сделать ? про нарушение целостности не будем - я админ и вправе отключить на время проверку) и вновь ее создал (в оригинальном виде).
В результате тот же запрос вернет:
id, parent:
1 - 0
0 - Null
И этот НД твой алгоритм изобразит в виде 2-ух корневых узлов , вместо того чтобы узел с Id=1 изобразить дочерним по отношению к узлу с Id = 0
Где я не прав ? Покажи ...
Palladin (2006-10-19 17:42:00) [14]вот серьезный косяк у себя нашел... строчка
theUnlinked.Delete(n);
ее нужно убрать, не нужна она.
Palladin (2006-10-19 17:38:00) [15]
В чем прелесть-то - исказить реальную иерархию ?
в общем я смотрю ты мельком взглянул на код, подробно не разобравшись в происходящем... плохо
Palladin (2006-10-19 17:36:00) [16]
> Сергей М. © (19.10.06 17:35) [48]
ай ай ай... ну в какой же корень то? не в корень, а в theUnlinked, то бишь временное хранилище беспризорников...
Сергей М. (2006-10-19 17:35:00) [17]
> там Else в конце строки м/у прочим
ну и влупишь ты при этом узел в корень, ибо родитель в TreeView не найден, потому что еще не добавлен, потому что он в НД фигурирует позжедобавляемого в дан.момент чада.
В чем прелесть-то - исказить реальнуюиерархию ?
Palladin (2006-10-19 17:34:00) [18]
> Нет, не придирки.
как это не придирки? обыкновенные придирки. что мешает прикрутить сортировку всех детей одного родителя по определенному критерию?
Palladin (2006-10-19 17:31:00) [19]
> В общем же случае запись о родителе не обязана фигурировать в НД раньше записи о его "чаде"
а в моем примере она как раз и не обязана фигурировать раньше, разберись пжалста в коде, попробуй логику понять...
Palladin (2006-10-19 17:30:00) [20]
> Чтой-то вдруг именно по caption ?
а просто так, что бы НД вернулся как в твоем примере, caption у меня там a b c d соответственно для каждой строчки, если глаза режет можешь order by убрать...
> А если это условие ложно ? Где у тебя его обработка ?
там Else в конце строки м/у прочим...