IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> бинарное дерево, программа зацикливается
сообщение
Сообщение #1


Гость






Помогите плиз!!Я не знаю, как исправить...
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. Или подсказать, как исправить...
Эта процедура должна найти количество вхождений элемента в дерево. Элемент дерева--запись о сотруднике...Заранее спасибо!!
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Правильно зацикливается... Какое условие задано, то и проверяется...
New(Root);
while Root<>Nil do ...

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

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

P.S. Никакого количества элементов дерева считаться не будет, ибо все то, как ты изменишь N внутри более "глубокой" рекурсии будет неизвестно в более "мелкой"... Используй Var хотя бы...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






Получается, что процедура делает обход дерева слева направо, параллельно сравнивая каждый элемент дерева. Так? Сравниваем эл-т дерева с введённым, пока указатель не станет равным nil. Логика хоть правильная у меня?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Телепаты на другом форуме. Ты не привела даже описания структуры, с которой работаешь. Что ты хочешь, чтобы тебе сказали? Что ошибка в 17-ой строке?

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

P.S. Вопрос об условии завершения рекурсии ты, я так понял, игнорируешь? Как знаешь... Только не удивляйся потом, что тебе ТОЖЕ не отвечают на те вопросы, которые ты задаешь...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Вот структура
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.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






А если вот так написать?
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(и остальные данные о сотруднике) абсолютно не похожи на правду...написан какой-то бред.ПОЧЕМУ??
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Катюшка, ты сначала сама разберись в алгоритме. У тебя есть логические ошибки. Например, переменная n передается в функцию (не описана как var), и при этом сразу зануляется..

И опиши подробнее задачу. И нам поможет, и тебе.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Значит так. Нужно написать рекурсивную процедуру или функцию, подсчитывающую количество вхождений элемента Е в бинарное дерево. Элемент Е вводится с клавиатуры. Вроде бы лего(наверняка легко), но не могу сделать эту задачку. Не получается...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






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 реализаций построения бинарного дерева, ищи...) - то вышеприведенная процедура должна работать...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Inc(n)-- это увеличение n на единицу, да?
Объясните мне пожалуйста, а почему вводить данные не нужно?
Ведь надо выбрать какой-то элемент дерева, кол-во которого будем определять.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Вот, что я наделала... (Показать/Скрыть)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Всё увидела и исправила))
 ...
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
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






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

А ты что делаешь? На каждом шаге рекурсии заново заполняешь 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. Файл данных можешь присоединить? И напиши, что именно ты вводишь для поиска...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Всё равно не считает количество этих элементов!!!!! Всё время выводит ноль... wacko.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






Я для поиска ввожу всё--ФИО, оклад и тд. Все поля, что есть. А файл не присоединяется...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Когда я делала отладку программы, оказалось, что в процедуре не сравниваются элементы дерева с вводимыми данными...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






Рассказать, почему?

Ты очень сильно путаешься при работе с глобальными и локальными переменными... А ведь это - основы... Посмотри то, что я присоединил. Эта программа отработала (без файла, мой вариант я закомментировал)...


Прикрепленные файлы
Прикрепленный файл  TreeKat.pas ( 3.04 килобайт ) Кол-во скачиваний: 253
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Всё вышло!!!!!!!!!!!!!!!!! Спасибо!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !mol1.gif
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 19.03.2024 17:59
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name