Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ 2 одноаправленных списка, обратный порядок

Автор: arr_lenny 29.12.2010 21:34

Задача такая
Дано 2 однонаправленных списка целых чисел.
Надо в первый список после максимального элемента вставить 2ой список, но в обратном порядке(вот с этим то обратным порядком проблемы)
Надеюсь на помощь, всех с Наступающим =)


type
list=^elem;
elem=record
info:integer;
next:list;
end;

var l,p,q,l2,p2,q2,w:list; x,y,max:integer;


begin
writeln('Первый');
new(l);
readln(x);
l^.info:=x;
p:=l;
while x<>0 do
begin
new(q);
readln(x);
q^.info:=x;
p^.next:=q;
p:=q;
end;
p^.next:=nil;

writeln('Второй');
new(l2);
readln(y);
l2^.info:=y;
p2:=l2;
while y<>0 do
begin
new(q2);
readln(y);
q2^.info:=y;
p2^.next:=q2;
p2:=q2;
end;
p2^.next:=nil;


p:=l;
max:=p^.info;
while p^.next<>nil do
begin
if p^.info>max then max:=p^.info;
p:=p^.next;
end;



p:=l; p2:=l2;
while p^.next<>nil do
begin
if p^.info=max then
begin
new(q);


q^.info:=p2^.info;
q^.next:=p^.next;
p^.next:=q;

p2:=p2^.next;


while p2^.next<>nil do
begin
new(w);
w^.info:=p2^.info;
p^.next:=w;
w^.next:=q;
w:=q;
p2:=p2^.next;
end;

end;
p:=p^.next;
end;

p^.next:=nil;
writeln('Измененный') ;
p:=l;
while p^.next<>nil do
begin
writeln(p^.info);
p:=p^.next;
end;
end.



Автор: !!FPA!! 30.12.2010 0:34

Я начну с небольшой критики.
Код очень трудно читать (отступы слишком хаотичны, пары begin/end на разных уровнях).
Переменные имеют нечитабельные имена.
Повторяющиеся операции (ввод списка, вывод списка на экран) лучше вынести в процедуры - тогда и переменных станет меньше.
Ошибка при вставке нового элемента в список.
"Хоть это и не педагогично" (цитата из к/ф "Завтрак на траве") мне легче привести прграммку


TYPE
List = ^Elem;
Elem = RECORD
Info : Integer;
Next : List;
END;

{заполнение списка случайными значениями}
PROCEDURE FillList(VAR Root : List);
VAR
i : Integer;
p : List;
BEGIN
New(Root);
Root^.Next:=NIL;
Root^.Info:=Random(100);
p:=Root;
for i:=1 to 10 do begin
New(p^.Next);
p:=p^.Next;
p^.Next:=NIL;
p^.Info:=Random(100);
end;
END;

{освобождение памяти от списка}
PROCEDURE ReleaseList (VAR Root : List);
VAR
p : List;
BEGIN
while Assigned(Root) do begin
p:=Root;
Root:=Root^.Next;
Dispose(p);
end;
END;

{вывод элементов списка на экран}
PROCEDURE ShowList ( Root : List);
BEGIN
while Assigned(Root) do begin
Write(Root^.Info:3);
Root:=Root^.Next;
end;
WriteLn;
END;

{возвращает указатель на максимальный элемент}
FUNCTION GetIndexMax( Root : List) : List;
VAR
Pmax : List;
BEGIN
Pmax:=Root;
while Assigned(Root) do begin
if Pmax^.Info<Root^.Info
then begin
Pmax:=Root;
end;
Root:=Root^.Next;
end;
GetIndexMax:=Pmax;
END;

{Indx - указатель на элемент списка,
за которым будет вставлен элемент со значением Info}
PROCEDURE InsertNode( VAR Indx : List;
Info : Integer
);
VAR
Node : List;
BEGIN
if Indx=NIL then Exit;
New(Node);
Node^.Info:=Info;
Node^.Next:=Indx^.Next;
Indx^.Next:=Node;
END;

VAR
Root1 : List; {начало списка 1}
Root2 : List; {начало списка 2}
Pmax : List; {указатель на максимальный элемент списка 1}
Indx : List; {указатель на текущий элемент в списке 2}
Node : List; {указатель на добавляемый элемент в список 1}
BEGIN
Root1:=NIL;
Root2:=NIL;
{заполнение списков случайными значениями}
Randomize;
FillList(Root1);
FillList(Root2);
{вывод списков на экран}
Write('List 1: ');
ShowList(Root1);
Write('List 2: ');
ShowList(Root2);
{получить указатель на максимальный элемент списка 1}
Pmax:=GetIndexMax(Root1);
{вставить элементы списка 2 в список 1 после максимального элемента}
Indx:=Root2;
while Assigned(Indx) do begin
InsertNode(Pmax, Indx^.Info);
Indx:=Indx^.Next;
end;
{вывод результата на экран}
WriteLn('Result');
Write('List 1: ');
ShowList(Root1);

ReleaseList(Root1);
ReleaseList(Root2);
END.

Автор: !!FPA!! 30.12.2010 0:53

Идея вставки следующая.
Нахоодим указатель на максимальный элемент списка 1.
Начинаем просматривать от начала список 2.
Каждый элемент из списка 2 вставляем в список 1 после максимального элемента.

Таким образом, по завершению просмотра списка 2 после максимального элемента будет находится последний элемент списка 2, потом предпоследний и т.д.

Это всё верно, если тоько не требовалось объединить оба списка в один. Но в этом случае всё почти тоже самое, но изменится процедура вставки и будет удалена строка вызова процедуры освобождения памяти от списка 2.

Автор: volvo 30.12.2010 2:38

Да что ж такое-то? Кто придумывает эти однотипные тупые задания? Кто постоянно штампует однотипные тупые решения??? Сколько раз можно задавать вопрос (задавал неоднократно, но почему-то ВСЕГДА он остается без ответа) : почему, собственно, разделяется первый элемент списка и все последующие? Что такого особенного есть в первом, что для его инициализации надо продублировать минимум три строки кода? Если уж первый элемент настолько примечателен, то куда его примечательность девается при выводе списка? Почему отдельно не печатается первый элемент, а потом - циклом все остальные? Это теперь так принято, программу сдавать "чем больше строк - тем она лучше"? Ошибки исправлять в подобной программе труднее ровно в 2 раза, если что.

P.S. Жду уточнения топикстартера каким образом происходит "вставка". Вставляется перевернутая копия списка_2? Сам список_2 в развернутом виде? В любом случае я бы не стал вставлять по одному элементу в одно и то же место первого списка. Гораздо проще (и правильней) будет "развернуть" второй, и одним действием поменять 2 указателя...

P.S. Я с гостями не общаюсь, если что, так что вопросы !!FPA!! может не задавать, я вопросы от гостей просто игнорирую. Будьте добры представиться, когда входите куда-то, а не сразу с порога начинать заявлять тут, что педагогично, а что - нет, скрываясь за пустой безликой маской "гость".