Модераторы: volvo877, Snowy, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Организация деревьев, в Паскаль 
:(
    Опции темы
Kaskad
  Дата 21.3.2005, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 324
Регистрация: 24.9.2004

Репутация: нет
Всего: 3



Интересует, как в Паскале реализовать деревья. smile smile


--------------------
Well come to America!
PM MAIL   Вверх
Fedor
Дата 21.3.2005, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



По-разному можно smile А какие деревья?
Можно с помощью динамических структур данных например. Да или просто с помощью матрицы.
Тут многое зависит от того, какие у тебя деревья: если двоичные например, то будет намного легче чем если у вершины может быть много потомков.


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
Zero
Дата 22.3.2005, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: нет
Всего: 24



Цитата(Kaskad @ 21.3.2005, 22:34)
Интересует, как в Паскале реализовать деревья.
ИМХО самый лучший способ, это использовать тип запись, реализованый в динамической памяти. Вот пример для бинарного дерева:
Код

Tree = ^cell;
    cell = record
      Name : string; {имя вершины}
      Parent, LP, RP : Tree; {указатели на предков, левых потомко и правых соответственно}
    end;

Это я использовал в своей курсовой работе, по теме "перевод инфиксной записи представленно бинарным деревом, в польскую"
PM MAIL ICQ   Вверх
Fedor
Дата 22.3.2005, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Если дерево не двоичное, т.е. может быть больше чем два потомка, то вместо LP и RP нужно использовать массив:
Код

Tree = ^cell;    
    cell = record    
      Name : string; {имя вершины}    
      Parent: Tree;
      branches:array[1..100] of tree;
    end;



--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
Pakshin A. S.
Дата 22.3.2005, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: нет
Всего: 61



А Parent обязателен? Некоторые задачки этого не требуют... smile
PM   Вверх
Kaskad
Дата 27.3.2005, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 324
Регистрация: 24.9.2004

Репутация: нет
Всего: 3



Как задать корень? и как добавлять новые эементы? нужно использовать New( что-то) ? А что именно? И как освобождать память? smile


--------------------
Well come to America!
PM MAIL   Вверх
Fedor
Дата 27.3.2005, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Вот, набросал быстро. Работает вроде правильно. С вопросами обращайся smile

Код
type
 tree=^cell;
 cell=record
  num:integer;
  key:integer;
  ln,rn:tree;
 end;

function FindNum(P:tree; K:integer):tree;  {Процедура пытается найти вершину с номером K}
var
 P1:tree;
 Q:tree;
begin
  p1:=p;
  if p1^.num=K then begin FindNum:=P1; exit; end;
  if P1^.ln<>nil then
   begin
     Q:=FindNum(P1^.ln,k);
     if Q<>nil then begin FindNum:=Q; exit; end;
   end;
  if P1^.rn<>nil then
   begin
     Q:=FindNum(P1^.rn,k);
     if Q<>nil then begin FindNum:=Q; exit; end;
   end;
  FindNum:=nil;
end;

procedure ClearStructure(P:tree); {Процедура очищает структуру}
begin
 if P^.ln<>nil then ClearStructure(P^.ln);
 if P^.rn<>nil then ClearStructure(P^.rn);
 Dispose(P);
end;

var
 P:tree;
 root:tree;
 f:text;
 from_,to_,key:integer;
begin
 new(root);
 root^.ln:=nil;
 root^.rn:=nil;
 root^.num:=1; {Номер корня изначально равен 1}
 root^.key:=0;

 assign(f,'input.txt'); reset(f);
 {Данные в текстовом фале расположены так: в каждой строке
    Номер_родителя Номер_потомка Вес_потомка}

 while not EOF(f) do
  begin
    readln(f,from_,to_,key);
    P:=findnum(root,from_); {Смотрим, существует ли уже вершина с номером from_}
    if P=nil then {если не существует, то выходим}
     begin
       writeln('Input error');
       readln;
       ClearStructure(root);
       close(f);
       halt;
     end;
    
    {здесь P - уже указатель на вершину с номером from_. Если у нее уже есть один потомок, то используем второй. Если нету, то используем первый}
    if P^.ln=nil then
     begin
       new(P^.ln);
       P:=P^.ln;
     end
    else
     begin
       new(P^.rn);
       P:=P^.rn;
     end;
    P^.ln:=nil;
    P^.rn:=nil;
    P^.num:=to_;
    P^.key:=key;
  end;

 {WORK WITH THE TREE}

 ClearStructure(root);
 close(f);
end.


Это сообщение отредактировал(а) Fedor - 27.3.2005, 15:49


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
Kaskad
Дата 27.3.2005, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 324
Регистрация: 24.9.2004

Репутация: нет
Всего: 3



У меня бинарные деревья- true|false smile
Я тоже тут состряпал: smile

Код

program derevo;
type
     tree= ^cell;
     cell= record
     zn:boolean;
     R,L: tree;
     end;

var
roof,son:tree;
sdeep,a:integer;

{poisk}
procedure find(e:tree;deep:integer);
begin
    with e^ do
    begin
    if (r=nil)or(l=nil) then if sdeep>deep  then begin sdeep:=deep;son:=e end;
    if (sdeep>=deep)then begin
                                                 find(r,deep+1);
                                                 find(l,deep+1);
                                                 end;
    end;
end;

{dobavlenie}

procedure add;
var son:tree;

begin
sdeep:=100;
son:=nil;
find(roof,1);
with son^ do If r=nil
          then begin new(r); r^.zn:=false; end
          else begin new(l); l^.zn:=true;  end;

end;


{vivod}
procedure print(e:tree;h:integer; deep:integer);
var i:integer;
begin
if e<>nil then begin for i:=0 to h*deep do
                         Write(' '); Writeln(e^.zn);end;
if e<> nil then
with e^ do
 begin
  if (L<> nil)and(deep<4) then print(L,h,deep+1);
  if (R<> nil)and(deep<4) then print(R,h,deep+1);
 end;
end;

{kill :) }
procedure kill(e:tree);
begin
if e<>nil then with e^ do
                      begin
                      if L<>nil then kill(L);
                      If R<>nil then kill(R);
                      If (L=nil)and(r=nil) then dispose(e);
                      end;
end;

{main}
BEGIN
Writeln('go..');
New(roof);

roof^.zn:=false;
for a:=1 to 10 do add;
print (roof,3,1);
kill(roof);
readln;
END.






Добавлено @ 16:47
.


и в 62 строке выдаёт ошибку! "Инвалит поинтер оператор" почему??? smile


--------------------
Well come to America!
PM MAIL   Вверх
Fedor
Дата 27.3.2005, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Kaskad Ты не обNILяешь потомков вершины при создании таковой.
Т.е. везде после new(smth) ты должен инициализировать потомков ее как nil.
Например:
Код

New(roof);    
roof^.zn:=false;
roof^.l:=nil;
roof^.r:=nil;


Кроме этого момента такое нужно сделать дважды в процедуре Add.

Кроме того, непонятен раздел переменных в процедуре Add. Насколько я понимаю, son должна быть глобальной переменной, так что в процедуре Add эту переменную нужно убрать.


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
Kaskad
Дата 30.3.2005, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 324
Регистрация: 24.9.2004

Репутация: нет
Всего: 3



Fedor Спасибо! smile

Значит дерево я создал. Всё отично работает. Теперь создаю процедуру random_add. То есть, чтоб добавляла листок к дереву случайно. Как это лучше сделать? Приходит на ум, сделать random(1024). Разложить в битовый массив из 10 элементов и спускаться по дереву с поворотами в право-1 и лево-0.

Может как-нибудь легче это дело можно организовать? smile


--------------------
Well come to America!
PM MAIL   Вверх
Kaskad
Дата 30.3.2005, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 324
Регистрация: 24.9.2004

Репутация: нет
Всего: 3



И ещё. У меня такое задание:

Определить уровень двоичного дерева, на катором находиться максимальное число вершин.

Раз 20 прочитал и ни чего не понял. Всегда будет корень - будет с максимальным количеством вершин. Или я не прав? smile


--------------------
Well come to America!
PM MAIL   Вверх
Fedor
Дата 30.3.2005, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Цитата(Kaskad @ 30.3.2005, 12:11)
Приходит на ум, сделать random(1024). Разложить в битовый массив из 10 элементов и спускаться по дереву с поворотами в право-1 и лево-0.

МОжно просто спускаться по дереву и постоянно рендомно генерировать либо 0 либо 1.

Цитата(Kaskad @ 30.3.2005, 14:12)
Определить уровень двоичного дерева, на катором находиться максимальное число вершин.

На уровне корня (пусть будет нулевой уровень) у тебя только одна вершина: корневая.
На первом уровне у тебя потомки корня - их может быть один либо два либо ноль.
На втором уровне соотв. от нуля до 2^2
И.т.д.

Тебе просто нужно обойти все дерево и считать кол-во вершин на каждом уровне...


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi"
THandle
Rrader
volvo877

Запрещается!

1. Обсуждать и делится взломанными компонентами или программным обеспечением

2. Публиковать ссылки на варез

3. Оффтопить

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема »


 




[ Время генерации скрипта: 0.1194 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.