Помощь - Поиск - Пользователи - Календарь
Полная версия: бинарное дерево
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
-Катюшка-
Помогите плиз!!Я не знаю, как исправить...
Procedure KolE(Root:TreePtr;n:Integer;Node:rabotnik);
Begin
 writeln('Введите элемент');
 Write('Введите ФИО сотрудника ');
 Readln(Node.FIO);
 Write('Введите год рождения сотрудника ');
 Readln(Node.godroj);
 Write('Введите пол сотрудника ');
 Readln(Node.pol);
 Write('Введите семейное положение сотрудника ');
 Readln(Node.cem);
 Write('Введите количество детей сотрудника ');
 Readln(Node.koldet);
 Write('Введите оклад сотрудника ');
 Readln(Node.oklad);
 n:=0;
 New(Root);
 while Root<>Nil do   {========Здесь зацикливается=====}
  if (Root^.data.FIO=Node.FIO) and (Root^.data.pol=Node.pol) and (Root^.data.cem=Node.cem) and
     (Root^.data.koldet=Node.koldet) and (Root^.data.oklad=Node.oklad) then
   n:=n+1;
  KolE(Root^.left,n,Node);
  KolE(Root^.right,n,Node);
  writeln('количество элементов равно',n);
End;

Здесь наверняка ещё куча ошибок, но помочь мне нужно только с while. Или подсказать, как исправить...
Эта процедура должна найти количество вхождений элемента в дерево. Элемент дерева--запись о сотруднике...Заранее спасибо!!
volvo
Правильно зацикливается... Какое условие задано, то и проверяется...
New(Root);
while Root<>Nil do ...

будет выполняться до тех пор, пока программа не прервется из-за невозможности выделить память по New...

Когда используется рекурсия ВСЕГДА нужно описывать условия ее прекращения. Вот ты сначала сформулируй, когда ты хочешь, чтобы рекурсия прекращалась, и мы тебе поможем это исправить...

P.S. Никакого количества элементов дерева считаться не будет, ибо все то, как ты изменишь N внутри более "глубокой" рекурсии будет неизвестно в более "мелкой"... Используй Var хотя бы...
-Катюшка-
Получается, что процедура делает обход дерева слева направо, параллельно сравнивая каждый элемент дерева. Так? Сравниваем эл-т дерева с введённым, пока указатель не станет равным nil. Логика хоть правильная у меня?
volvo
Телепаты на другом форуме. Ты не привела даже описания структуры, с которой работаешь. Что ты хочешь, чтобы тебе сказали? Что ошибка в 17-ой строке?

Ну, сделала ты New(Root)... А как Node с этим самым Root-ом связан? Как данные в Root^.Data появляются? Ты же ничего туда не заносишь...

P.S. Вопрос об условии завершения рекурсии ты, я так понял, игнорируешь? Как знаешь... Только не удивляйся потом, что тебе ТОЖЕ не отвечают на те вопросы, которые ты задаешь...
Гость
Вот структура
Type
  rabotnik=record
   number:integer;
   FIO:string[15];
   godroj:integer;
   pol:char;
   cem:string[15];
   koldet:integer;
   oklad:integer;
  end;
 TreePtr=^Tree;
 Tree=record
      data:rabotnik;
      left,right:TreePtr;
      end;
 rab=file of rabotnik;

Var
 Root:TreePtr;
 r,Node:rabotnik;

Данные берутся из предварительно подготовленного файла.
А условие завершения рекурсии, это вероятно root=nil.
-Катюшка-
А если вот так написать?
Procedure KolE(Root:TreePtr;n:Integer;Node:rabotnik);
var kol:integer;
Begin
 n:=0;
 if root<>nil then begin
  writeln('Введите элемент');
  Write('Введите ФИО сотрудника ');
  Readln(Node.FIO);
  Write('Введите год рождения сотрудника ');
  Readln(Node.godroj);
  Write('Введите пол сотрудника ');
  Readln(Node.pol);
  Write('Введите семейное положение сотрудника ');
  Readln(Node.cem);
  Write('Введите количество детей сотрудника ');
  Readln(Node.koldet);
  Write('Введите оклад сотрудника ');
  Readln(Node.oklad);
  kol:=0;
  while Root<>Nil do
   if (Root^.data.FIO=Node.FIO) and (Root^.data.pol=Node.pol) and       (Root^.data.cem=Node.cem) and
     (Root^.data.koldet=Node.koldet) and (Root^.data.oklad=Node.oklad) then
    kol:=kol+1;
  KolE(Root^.left,n,Node);
  KolE(Root^.right,n,Node);
  n:=n+kol;
  writeln('количество элементов равно',n);
  end;
End;

Вот только при отладке программы в root^.data.FIO(и остальные данные о сотруднике) абсолютно не похожи на правду...написан какой-то бред.ПОЧЕМУ??
Lapp
Катюшка, ты сначала сама разберись в алгоритме. У тебя есть логические ошибки. Например, переменная n передается в функцию (не описана как var), и при этом сразу зануляется..

И опиши подробнее задачу. И нам поможет, и тебе.
Гость
Значит так. Нужно написать рекурсивную процедуру или функцию, подсчитывающую количество вхождений элемента Е в бинарное дерево. Элемент Е вводится с клавиатуры. Вроде бы лего(наверняка легко), но не могу сделать эту задачку. Не получается...
volvo
Procedure Count_E(Root:TreePtr; Var n:Integer; E:rabotnik);
Begin
  {
    Вводить данные здесь не нужно...
    Эта процедура только подсчитывает количество элементов,
    равных E в уже сформированном ранее дереве
  }
  If Root <> Nil Then Begin
    With Root^.Data Do
      If
        (FIO=E.FIO) and (pol=E.pol) and (cem=E.cem) and
        (koldet=E.koldet) and (oklad=E.oklad) then Inc(n);
    Count_E(Root^.left, n, E);
    Count_E(Root^.right, n, E);
End;

Распечатывать результат тоже не нужно прямо внутри процедуры... Делай это после ее вызова...

Если дерево у тебя будет сформировано правильно (на форуме уже есть по крайней мере 10 реализаций построения бинарного дерева, ищи...) - то вышеприведенная процедура должна работать...
-Катюшка-
Inc(n)-- это увеличение n на единицу, да?
Объясните мне пожалуйста, а почему вводить данные не нужно?
Ведь надо выбрать какой-то элемент дерева, кол-во которого будем определять.
-Катюшка-
Вот, что я наделала... (Показать/Скрыть)
-Катюшка-
Всё увидела и исправила))
 ...
Procedure Count_E(Root:TreePtr;Var n:Integer;E:rabotnik); {Эта процедура всё-таки не хочет ничего делать!!!!}
Begin
 writeln('Введите элемент');
 Write('Введите ФИО сотрудника ');
 Readln(Е.FIO);
 Write('Введите год рождения сотрудника ');
 Readln(Е.godroj);
 Write('Введите пол сотрудника ');
 Readln(Е.pol);
 Write('Введите семейное положение сотрудника ');
 Readln(Е.cem);
 Write('Введите количество детей сотрудника ');
 Readln(Е.koldet);
 Write('Введите оклад сотрудника ');
 Readln(Е.oklad);
If Root<>Nil then begin
 With Root^.data do
  If (FIO=E.FIO) and (pol=E.pol) and (cem=E.cem) and (koldet=E.koldet)
  and (oklad=E.oklad) then Inc(n);
 Count_E(Root^.left,n,E);
 Count_E(Root^.right,n,E);
 end;
End;
...

Но всё равно не работает!!!!!!!!!!!!!!!!! mega_chok.gif
volvo
-Катюшка-, ну сколько раз говорить? Ты должна сначала заполнить элемент для поиска, а уже потом - ИСКАТЬ его в дереве!!!

А ты что делаешь? На каждом шаге рекурсии заново заполняешь E? Смысл в чем?

Procedure Count_E(Root:TreePtr;Var n:Integer;E:rabotnik);
Begin
  If Root<>Nil then begin
    With Root^.data do
      If
        (FIO=E.FIO) and (pol=E.pol) and (cem=E.cem) and
        (koldet=E.koldet) and (oklad=E.oklad) then Inc(n);
    Count_E(Root^.left,n,E);
    Count_E(Root^.right,n,E);
  end;
End;
...
  case key of
   '1':OrgTree;
   '2':Begin
        writeln('Выполняется процедура просмотра дерева');
        writeln;
        i:=0;
        Prosmotr(Top);
        Otobr(Top,1);
      readln;
     end;
   '3':Begin
      writeln('Введите элемент');
      Write('Введите ФИО сотрудника '); Readln(Еlement.FIO);
      Write('Введите год рождения сотрудника '); Readln(Еlement.godroj);
      Write('Введите пол сотрудника '); Readln(Еlement.pol);
      Write('Введите семейное положение сотрудника '); Readln(Еlement.cem);
      Write('Введите количество детей сотрудника '); Readln(Еlement.koldet);
      Write('Введите оклад сотрудника '); Readln(Еlement.oklad);

      Count_E(Root, n, Element);
      writeln('Количество вхождений элемента Е в дерево=',n);
      readln;
     end;
   end; { case }


Цитата
всё равно не работает!
В чем это выражается? Зависает? Вылетает? Зацикливается?

P.S. Файл данных можешь присоединить? И напиши, что именно ты вводишь для поиска...
-Катюшка-
Всё равно не считает количество этих элементов!!!!! Всё время выводит ноль... wacko.gif
Гость
Я для поиска ввожу всё--ФИО, оклад и тд. Все поля, что есть. А файл не присоединяется...
Гость
Когда я делала отладку программы, оказалось, что в процедуре не сравниваются элементы дерева с вводимыми данными...
volvo
Рассказать, почему?

Ты очень сильно путаешься при работе с глобальными и локальными переменными... А ведь это - основы... Посмотри то, что я присоединил. Эта программа отработала (без файла, мой вариант я закомментировал)...
-Катюшка-
Всё вышло!!!!!!!!!!!!!!!!! Спасибо!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !mol1.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.