Помощь - Поиск - Пользователи - Календарь
Полная версия: списки-динамическая структура
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
reboot
помогите с такой задачей:
Дан список, состоящий из N вещественных чисел. Удалить из него те звенья, значения которых меньше следующих. Организовать вывод начальной и конечной последовательности значений в списке.
вопрос первый: сдесь нужен массив записей, или можно обойтись нетипизированным файлом?
вопрос второй: если использовать массив то как обращаться к элементу списка при его заполнении рандомными числами?
понимаю что вопросы глупые и легкие(для кого-то), но у меня просто не очень хорошо общение со списками идет.
volvo
Список - это список. Если ты хочешь реализовать его на массиве, он теряет все преимущества. Так что никаких массивов и файлов тебе не надо, просто получай как-то очередное значение (ну, или генерируй рандомно), потом выделяй память под элемент списка и устанавливай указатели. Примеров на списки было очень много, в FAQ-е есть модули для работы со списками. Что именно у тебя вызывает затруднение?
reboot
прошу прощения, я понял свою ошибку. У меня просто в голове не укладывалось понимание самой структуры списка, и поэтому я думал что ее можно построить на основе массива(дурак). Вобщем я разобрался.
reboot
вобщем проблем не избежал, задача такая: Дан список, состоящий из N вещественных чисел. Удалить из него те звенья, значения которых меньше следующих. Организовать вывод начальной и конечной последовательности значений в списке.
проблема как раз в части кода которая отвечает за поиск и удаление... можите поправить ??

 uses crt;
type ukazatel=^elem_spiska;
elem_spiska=record
znach:integer;
sled:ukazatel;
end;
var number,i,j,r:integer;
temp,root:ukazatel;
begin
clrscr;
randomize;
number:=random(10);
root:=nil;
for i:=1 to number do
begin
temp:=root;
new(root);
with root^ do
begin
znach:=random(50);
sled:=temp;
end;
end;
temp:=root;
for i:=1 to number do begin
writeln('§­ зҐ­ЁҐ = ',temp^.znach);
temp:=temp^.Sled;
end;
temp:=root;

for i:=1 to number do begin
if temp^.znach < temp^.sled^.znach then
begin
temp^.znach:=temp^.sled^.znach;
temp^.sled:=nil;
end;
end;

writeln;
for i:=1 to number do begin
writeln('§­ зҐ­ЁҐ[2] = ',temp^.znach);
temp:=temp^.Sled;
end;
readln;


end.



volvo
for i:=1 to number do begin
if temp^.znach < temp^.sled^.znach then ...
Вот так делать нежелательно... У тебя список, который заполнять можно циклом For, а обрабатывать потом нужно по-другому: "пока указатель не станет Nil" (запомни указатель на начало списка, иначе его потеряешь)...
reboot
дело в том, что при выполнении условия мне надо передвинуть указатель так, чтобы предыдущий элемент списка указывал на следующий за следующим...то есть возвращаться к предыдущему и указывать на следующий за следующим....но как так сделать я не знаю.
volvo
Смотри. Тебе надо идти на один элемент "позади" проверяемой пары, чтобы ты мог контролировать указатель текущего элемента, и (если надо), перебросить его через один элемент:
temp := root;
while (temp^.sled <> nil) and (temp^.sled^.sled <> nil) do begin
{ проверяем пару: следующий и который за ним, текущий не трогаем... }
if temp^.sled^.znach < temp^.sled^.Sled^.znach then begin
t2 := temp^.sled; { <--- Запоминаем элемент, нам его надо будет удалить }
temp^.sled := t2^.sled; { корректируем указатели (перепрыгиваем через temp^.sled) }
dispose(t2); { Теперь можно удалять меньший элемент }
end
else temp := temp^.sled; { если ничего из списка не удалялось - продвигаемся дальше }
end;
Но... При таком проходе по списку одна пара от тебя ускользнет: это самый первый и второй элементы, они не будут сравниваться, сравнение начнется с пары "второй - третий". Это нехорошо. Чтоб решить проблему - введи еще одну переменную, типа Boolean, и перед проходом, который я показал, присвой ей True если root^.znach < root^.sled^.znach... Иначе - False.

Что это тебе даст? Потом, после прохода, и удаления меньших элементов в паре, тебе надо напечатать список? Вот если переменная равна True, удалишь из списка первый элемент, а потом начнешь печатать. Если False - ничего делать не надо, первый элемент не меньше второго, и его удалять не надо.

Теперь о печати списка. Опять же, не делается это через цикл For, вот так надо:
temp := root;
while temp <> nil do begin
writeln('список[2] = ', temp^.znach);
temp:=temp^.Sled;
end;


Попробуй реализовать... Это не сложно, просто надо понять алгоритм. Начерти список со связями на бумаге, и разберись, что делается в том алгоритме, который я привел, что чему присваивается... Когда разберешься - будешь щелкать такие задачи как семечки smile.gif
reboot
спасибо огромное! ты тут описал как раз то что мне было не понятно=) впринципе стало все более яснее, но разбираться еще придется много..
reboot
появился новый вопрос: когда я "корню" присваиваю ссылку на второй элемент то ни чего не происходит...
но первый элемент удаляется же так??

Добавлено через 2 мин.
Цитата(reboot @ 5.06.2009 19:14) *

появился новый вопрос: когда я "корню" присваиваю ссылку на второй элемент то ни чего не происходит...
но первый элемент удаляется же так??

простите..проблема была в паскале...стоило поменять версию как все заработало+)
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.