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

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

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

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





Группа: Пользователи
Сообщений: 2
Пол: Мужской

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


Здравствуйте, уважаемые форумчане. Есть такое задание:
Удалить из списка один элемент после первого элемента с нулевым значением, если его значение отлично от него.

Написал я для этого дела такую процедуру:

procedure DelX(var start:link);
var p,pr:link;
k:integer;
begin
Writeln('Удаление из списка первого элемента после нуля (если это не ноль)');
k:=0;
p:=start;
while (k=0) AND (p<>nil) do
begin
if (p^.inf=0) then
begin
p:=p^.next;
if (p^.inf=0) then k:=1
else
begin
pr^.next:=p^.next;
dispose(p);
p:=pr^.next;
k:=1;
end;
end
else begin pr:=p; p:=p^.next; end;
end;
if k=0 then writeln('Ни одного нуля не найдено.');
Write('Нажмите любую клавишу');
readln;
end;



Но она очевидно неправильная. Во-первых, когда после нуля идет число, то она удаляет не только это число, но и сам нуль. Когда два нуля подряд - все нормально. Во-вторых программа вылетает, когда список начинается с нуля.
Буду очень благодарен, если сможете указать на мои ошибки.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Ну, вылетает тебя процедура по самой распространенной причине: невнимательность. Вот тут:
Цитата
            pr^.next:=p^.next;
чему равно pr, можно полюбопытствовать? Мусор. Все, тебе практически гарантирован вылет неизвестно куда, естественно, что результатам программы (даже если она отработает до конца) верить после этого нельзя.

А вообще - несколько сумбурно ты решаешь задачу. Я бы делал так:

// Во-первых, напрасно ты передаешь start как Var-параметр.
// Первый элемент списка не будет удален никогда. Он либо не 0 и его пропустишь,
// либо он 0, и тогда в лучшем случае удалится следующий за ним...
procedure DelX(start: link);
var
p, pr: link;
begin
// Начали:
p := start;
repeat
// для начала - пропускаем все ненулевые элементы, при этом
// следя за концом списка, чтоб без неожиданностей...
while (p <> nil) and (p^.inf <> 0) do p := p^.next;

// когда мы тут - это значит либо нашли 0, либо дошли до конца списка
// если дошли до конца - то p = nil, и внутрь If мы просто не попадаем...
if p <> nil then
begin
// ага, мы тут, значит, p указывает на элемент равный 0...
// запомним его (вдруг следующий будем удалять) и переходим к следующему...
pr := p;
p := p^.next;

// Не вылезли из списка? Не нулевой элемент? Удаляем и правим указатель от предыдущего...
// после удаления выходим из процедуры !!!
if (p <> nil) and (p^.inf <> 0) then
begin
pr^.next := p^.next;
dispose(p); exit;
end;
end;

// не вышли из процедуры? Одно из двух. Либо конец списка, либо несколько нулей подряд
// в случае конца списка p = nil, и цикл repeat заканчивается, иначе - продолжаем поиск...
until p = nil;
end;
Что непонятно - задавай вопросы. Упустишь - потом будешь плавать в динамических структурах... smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3





Группа: Пользователи
Сообщений: 2
Пол: Мужской

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


Ох, спасибо огромное. Насчет плавать - это вы абсолютно в точку, упустил эту тему почти полностью (раньше знал, думал что и сейчас без проблем вспомню), в итоге пришлось рассматривать её полностью на чужих примерах, которые сами по себе были далеко от оптимальных =) Так что вот сейчас ещё параллельно делаю задания по двусвязным спискам и деревьям - получается все также криво (а сдавать-то уже сегодня надо)

Конкретно по этому вопросов нет, комментарии весьма подробны, ошибки свои осознал, ещё раз спасибо!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 





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