Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.09.2010, 13:50   #1
Gonzo
Форумчанин
 
Аватар для Gonzo
 
Регистрация: 07.03.2009
Сообщений: 123
Вопрос Описание структуры данных n-арного (k-ичного) дерева

Доброго времени суток!
Встал вопрос описания n-арного (k-ичного) дерева. Т.е. дерева в котором у каждого узла может быть произвольное число потомков. Тонкость в том, что узлы (не имеющие потомков) должны содержать одно информационное поле, а листы несколько инф. полей. Все эти танцы с бубном направлены на описание древовидной структуры организации.
Вот что накропал:
Код:
type
 pPersonal = ^Personal;
 pWorkMan  = ^WorkMan;

 WorkMan = record
  name,prof,jobt,task:string;
  age:integer;
  parent:pPersonal;
  next,prev:pWorkMan;
 end;

 Personal=record
  info:string;
  parent,child:pPersonal;
  next,prev:pPersonal;
  workmans:pWorkMan;
 end;

var
  Org:pPersonal;
Думаю есть более изящный способ описания.
Еще сложность заключается в том, что необходимо сохранять дерево в файл и загружать дерево из файла. Буду так же благодарен за пинки в этом направлении.
Не говорите что мне делать, и я не скажу куда Вам идти.
Пишу программы на заказ на Delphi и Pascal
Форум разработчиков Pascal и Delphi
Gonzo вне форума Ответить с цитированием
Старый 21.09.2010, 14:23   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Думаю есть более изящный способ описания.
Код:
TItem=class
 Data:string;
 Children:TObjectList;
end;
Класс, содержащий данные, и список детей.
Каждый Child представляет собой экземпляр класса TItem.
Короче говоря не изобретать велик, а посмотреть как в TreeView сделано
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 21.09.2010, 14:40   #3
vedro-compota
любитель-далеко не
Участник клуба
 
Аватар для vedro-compota
 
Регистрация: 13.04.2010
Сообщений: 1,156
По умолчанию

Цитата:
Еще сложность заключается в том, что необходимо сохранять дерево в файл и загружать дерево из файла.
дерево рекурсивной процедурой создаёшь?
против абортов=за + жизнь;.фкн вгу;_______________________мойблг
vedro-compota вне форума Ответить с цитированием
Старый 21.09.2010, 15:12   #4
Gonzo
Форумчанин
 
Аватар для Gonzo
 
Регистрация: 07.03.2009
Сообщений: 123
По умолчанию

Тогда так?
Код:
TNode=class
 Data:string;
 Children:TObjectList;
end;

TSheet=class
 name,prof,jobt,task:string;
 age:integer;
end;
--------------
vedro-compota, рекурсивной
Не говорите что мне делать, и я не скажу куда Вам идти.
Пишу программы на заказ на Delphi и Pascal
Форум разработчиков Pascal и Delphi

Последний раз редактировалось Gonzo; 21.09.2010 в 15:15.
Gonzo вне форума Ответить с цитированием
Старый 21.09.2010, 15:45   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
TSheet=class
Это зачем?
Одного класса хватит. Яж говорю посмотри в генофонд на TreeView это оч. полезное занятие для изучения механизма деревьев.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 21.09.2010, 16:23   #6
Gonzo
Форумчанин
 
Аватар для Gonzo
 
Регистрация: 07.03.2009
Сообщений: 123
По умолчанию

TNode (лучше наверно назвать TTree) - класс узлов
TSheet - класс листов (не имеющий потомков)
Такое разделение из-за того что в листах нам нужно хранить доп. информацию.
Мы же можем в TObjectList хранить любые объекты производные от TObject?
----------------------------------------------------------------------------
Изначально предполагалось для визуализации использовать TreeView,
я вот думаю может всё сделать на основе TreeView без промежуточной структуры?
- При выборе файла загружать структуру дерева из файла;
- При выборе листа в дереве, обращаться напрямую к файлу для просмотра сведений листа (сотрудника);
- При выходе из программы/при смене файла данных перезаписывать файл данных.
Но тогда встает вопрос привязки нодов дерева к данным файла.
И соответственно по прежнему остаётся вопрос чтения/записи данных из/в файл.
Может имеет смысл хранить данные в двух файлах?
В одном структуру дерева (организации), а в другом непосредственно данные о сотрудниках (листах)?
Не говорите что мне делать, и я не скажу куда Вам идти.
Пишу программы на заказ на Delphi и Pascal
Форум разработчиков Pascal и Delphi
Gonzo вне форума Ответить с цитированием
Старый 21.09.2010, 16:30   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Gonzo
Тогда каждый экземпляр TTree должен содержать список из TSheet.
Цитата:
Может имеет смысл хранить данные в двух файлах?
Запутаешся.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.09.2010, 13:19   #8
Gonzo
Форумчанин
 
Аватар для Gonzo
 
Регистрация: 07.03.2009
Сообщений: 123
По умолчанию

Цитата:
Яж говорю посмотри в генофонд на TreeView это оч. полезное занятие для изучения механизма деревьев.
Код:
 TTreeNode = class
  private
    FParent: TTreeNode;
    FChilds: TObjectList;
    function GetChild(Index: Integer): TTreeNode;
    function GetCountChild: Integer;
  public
    Caption: TCaption;
    Data: TObject; //создаём объект с данными если надо
    constructor Create(AParent: TTreeNode);
    property Parent : TTreeNode read FParent;
    property Childs[Index: Integer]: TTreeNode read GetChild;
    property CountChild: Integer read GetCountChild;
    procedure AddChild(AChild: TTreeNode);
    procedure DeleteChild(AChild: TTreeNode); overload;
    procedure DeleteChild(Index: Integer); overload;
  end;
 
implementation
 
constructor TTreeNode.Create(AParent: TTreeNode);
begin
  FParent:= AParent;
  FChilds:= TObjectList.Create(False);
  if (FParent <> nil) then
    FParent.AddChild(Self);
end;
 
function TTreeNode.GetChild(Index: Integer): TTreeNode;
begin
  Result:= TTreeNode(FChilds.Items[Index]);
end;
 
function TTreeNode.GetCountChild: Integer;
begin
  Result:= FChilds.Count;
end;
 
procedure TTreeNode.DeleteChild(AChild: TTreeNode);
begin
  AChild.FParent:= nil;
  FChilds.Remove(AChild);
end;
 
procedure TTreeNode.DeleteChild(Index: Integer);
begin
  Childs[Index].FParent:= nil;
  FChilds.Delete(Index);
end;
 
procedure TTreeNode.AddChild(AChild: TTreeNode);
begin
  if (FChilds.IndexOf(AChild) < 0) then
    FChilds.Add(AChild);
end;
Не говорите что мне делать, и я не скажу куда Вам идти.
Пишу программы на заказ на Delphi и Pascal
Форум разработчиков Pascal и Delphi
Gonzo вне форума Ответить с цитированием
Старый 22.09.2010, 13:57   #9
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Делал как-то давно программку для инвентаризации. Можешь пошарить. Может чего понравится.
Инвентаризация.zip
Sibedir вне форума Ответить с цитированием
Старый 22.09.2010, 20:06   #10
Gonzo
Форумчанин
 
Аватар для Gonzo
 
Регистрация: 07.03.2009
Сообщений: 123
По умолчанию

Cо структурой разобрался.
Загрузку/сохрание решил сделать в файл XML.
Работаю с XMLDocument, Delphi 7.
Так как у меня содержать атрибуты будут только листья, то возникла проблема определения наличие атрибутов у тега.
Именно не наличие какого-то определенного атрибута (XMLDocument.ChildNodes[i].HasAttribute('имя атрибута')), а наличие атрибутов как таковых. Т.е. нужно определять имеет ли тэг не менее одного атрибута.
Это всё для того, чтобы при построении дерева, если тег (узел XML файла) имеет атрибуты, то мы формируем обьект Data (для класса из сообщения выше).
Если НЕ имеет, то Data:=nil, а Caption:='Текст из тега'.

Отойду пока от определения наличия атрибутов у тегов XML...
Столкнулся вот с чем:
накидал такую процедуру для обхода XML и визуализации дерева:
Код:
var MainTree: TTreeView;
     XMLDoc: TXMLDocument;

procedure TMianForm.BuildTree(XMLNodeList:IXMLNodeList; ParentNode:TTreeNode);
var i:integer;
    BufXMLNodeList:IXMLNodeList;
    BufParentNode:TTreeNode;
begin
 if XMLNodeList.Count>0 then
  begin
   i:=XMLNodeList.Count;
   while i>0 do
    begin
     if (XMLNodeList[XMLNodeList.Count-i].nodeName<>'xml') then
      begin
       BufParentNode:=MainTree.Items.AddChild(ParentNode,XMLNodeList[XMLNodeList.Count-i].NodeName);
       if XMLNodeList[XMLNodeList.Count-i].HasChildNodes then
        begin
         BufXMLNodeList:=XMLNodeList[XMLNodeList.Count-i].ChildNodes;
         BuildTree(BufXMLNodeList,BufParentNode);
        end;
      end;
     dec(i);
    end;
  end;
end;

//вызов:
procedure TMianForm.XMLFileToTree(SourceFileName:String);
begin
 Try
  LockWindowUpdate(MainTree.Handle);
  XMLDoc.LoadFromFile(SourceFileName);
  BuildTree(XMLDoc.ChildNodes,nil);
 finally
  LockWindowUpdate(0);
 end;
end;
,но нодов в XMLNodeList больше чем кол-во тегов XML-документа.
Никто не просветит по этому поводу?
Не говорите что мне делать, и я не скажу куда Вам идти.
Пишу программы на заказ на Delphi и Pascal
Форум разработчиков Pascal и Delphi

Последний раз редактировалось Stilet; 23.09.2010 в 08:05.
Gonzo вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Dll библиотека, описание нескольких типов данных Vol666 Общие вопросы Delphi 2 19.05.2010 12:13
СИ. Списки. Описание структуры односвязного списка Jane-sad Помощь студентам 9 17.05.2010 14:40
Запись в массив данных бинарного дерева m9yt Общие вопросы C/C++ 2 14.03.2010 12:49
[C++] Описание структуры TORT sasha20666 Помощь студентам 3 31.10.2009 17:52
[C] Абстрактные типы данных. Реализация дерева общего вида. Dju Помощь студентам 0 11.05.2009 18:11