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

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

Форум «Всё о Паскале» _ Задачи _ сортировка+список

Автор: Rabbit 26.05.2007 21:33

надо отсортировать список по ключевому признаку, у меня все сортируется но обратно не записывается в список! подскажите где ошибка!
Может чтото с параметрами??


PROCEDURE SORT ( FIRST : EL);
TYPE
MAS1=ARRAY[1..100] OF INTEGER;
TMAS1=^MAS1;
MAS2=ARRAY[1..100] OF STRING;
TMAS2=^MAS2;
VAR
Z1:TMAS1;
Z2: TMAS2;
K,C,i,j: INTEGER;
D: STRING;
BEGIN
Q:=FIRST;
K:=0;
WHILE Q<> NIL DO
BEGIN
INC(K);
Z1^[K]:=Q^.INF1;
Z2^[K]:=Q^.INF2;
q:=q^.next;
END;

FOR J:=1 TO K-1 DO
FOR I:=1 TO K-J DO
IF Z1^[I]>Z1^[I+1]
THEN BEGIN
C:=Z1^[I];
Z1^[I]:=Z1^[I+1];
Z1^[I+1]:=C;
D:=Z2^[I];
Z2^[I]:=Z2^[I+1];
Z2^[I+1]:=D;
END;
{запись обратно в список}
q:=nil;
FIRST:=NIL;
FOR I:=1 TO K DO
BEGIN
new(p);
if first=nil then first:=p;
p^.inf1:=Z1^[i];
p^.inf2:=Z2^[i];
if q<>nil then q^.next:=p;
q:=p;
end;
p^.next:=nil;

writeln ('Operaciya vipolnena! Nagmite ENTER');
readkey;
END;

{ВЫЗОВ}
sort(first);




помогите пожалуйста!

Автор: volvo 26.05.2007 22:43

Если бы ты во-первых сделал так:

PROCEDURE SORT ( Var FIRST : EL);
, а во-вторых выделал бы память для массивов, в которых собираешься сортировать данные:

...
BEGIN
New(Z1); New(Z2); { <--- Не забывай это возвращать потом }
Q:=FIRST;
...

, то все бы работало...

Но утечка памяти все же есть: ты читаешь данные из первоначального списка, не удаляя их из памяти, а потом зачем-то организуешь новый список, т.е., расход памяти увеличивается вдвое... А удалишь ты в конце работы программы - только новый список (если вообще удалишь)...

Автор: Rabbit 27.05.2007 0:01

Спасибо исправила, все работает
а вот еще два кусочка:
тоже не работают
1, Поменять местами элемент с заданным ключом и следующий


PROCEDURE CHANGE ( FIRST : EL; Q : EL);
VAR
T, R : EL;
x : INTEGER;
ok: boolean;
BEGIN
q :=first;
while q<>nil do
begin
writeln (q^.inf1,' ',q^.inf2);
q:=q^.next;
end;
writeln ('Vvedite znachenie kluchevogo priznaka');
readln(x);
r:= first;
ok:= true;
while (r<>nil) and ok do
if r^.inf1=x then begin
q:=r ;
ok:= false;
end
else r:=r^.Next;
if ok=true
then begin
writeln (' takogo el net' );
exit;
end;

if q<> nil
then begin
T:=Q;
Q:=Q^.NEXT;
Q^.NEXT:=T;
end;
writeln ('Operaciya vipolnena! Nagmite ENTER');
readkey;
END;

вызов: change(FIRST,Q)





2. Исключить элемент перед i-ым элементом


PROCEDURE DEL_BEF_I( FIRST : EL; I : INTEGER);
VAR R : EL;
K ,N : INTEGER;
BEGIN
print;
writeln('Vvedite i ');
readln(i);
N:=COUNT_EL(FIRST);
IF (I<1) OR (I>N)
THEN BEGIN
WRITELN ('i zadano nekorrektno');
EXIT;
END
ELSE IF I=1
THEN WRITELN ('NET EL-TA PERED')
ELSE BEGIN
WRITELN ( ' YDALIT ELEMENT ? [Y-DA]' );
READLN ( ANS);
IF ANS='Y'
THEN BEGIN
IF I=2
THEN BEGIN {ydal 1 el}
T := FIRST;
FIRST:= FIRST^.NEXT;
DISPOSE ( T);
END
ELSE BEGIN
T := FIRST;
Q := NIL;
K := 1;
WHILE (K<I-1) DO
BEGIN
K := K+1;
Q := T;
T := T^.NEXT;
END;
BEGIN
R := T^.NEXT;
Q^.NEXT := R;
DISPOSE ( T ); {ydal i-1 }
END;
END;

END;
q :=first;
while q<>nil do
begin
writeln (q^.inf1,' ',q^.inf2);
q:=q^.next;
end;
readkey;
writeln ('Operaciya vipolnena! Nagmite ENTER');
readkey;
END;

END;

вызов: del_bef_i(first,i);


Автор: мисс_граффити 27.05.2007 3:20

1. Основная ошибка у тебя здесь:

            T:=Q;
Q:=Q^.NEXT;
Q^.NEXT:=T;

не до конца меняешь.
у тебя ведь еще есть указатель с предыдущего элемента на первый из меняемых...

как правильно сделать - пока не могу однозначно сказать. не знаю, что по этому заданию надо делать, если получится, что такой ключевой признак у последнего элемента. с чем его менять?

второе пока не смотрела, но что-то ты сильно намудрила...
ну и попутный вопрос: как удалять элемент перед первым? просто писать, что это невозможно?

Автор: Rabbit 27.05.2007 14:41

1, в первом задании можно просто вывести сообщение что "операция не можнт быть выполнена"
а разве надо не просто менять через третью переменную??

2, там если первый то у меня написано "нет элемента перед" и ничего не делается


Автор: мисс_граффити 27.05.2007 20:39

немножко подправила первую (теперь по крайней мере иногда работает):

PROCEDURE CHANGE (var FIRST : List);
VAR
T, Q: List;
x : INTEGER;
ok: boolean;
BEGIN
q :=first;
while q<>nil do
begin
writeln (q^.info);
q:=q^.next;
end;
writeln ('Vvedite znachenie kluchevogo priznaka');
readln(x);
t:= first;
ok:= true;
if t^.info=x then
begin
first:=first^.next;
t^.next:=t^.next^.next;
first^.next:=t;
end
else
begin
while (t^.next^.next<>nil) and ok do
if t^.next^.info=x then
begin
q:=t;
ok:=false;
end
else
t:=t^.Next;

if ok then
begin
writeln ('neponyatno, shto menyat!' );
readln;
exit;
end;

if q<>nil then
begin
T:=Q^.Next;
Q^.Next:=Q^.NEXT^.Next;
T^.Next:=Q^.Next^.Next;
Q^.next^.next:=T;
end;
end;
writeln ('Operaciya vipolnena! Nagmite ENTER');
readkey;
END;

Автор: Rabbit 28.05.2007 17:40

Цитата(мисс_граффити @ 27.05.2007 16:39) *


PROCEDURE CHANGE (var FIRST : List);

writeln ('Vvedite znachenie kluchevogo priznaka');
readln(x);
t:= first;
ok:= true;
if t^.info=x then
begin
first:=first^.next;
t^.next:=t^.next^.next;
first^.next:=t;
end

в верхнем кусочке получается так:
1. первому присваиваешь второй
2, второму присваиваешь третий
3, второму присваивашь первый
зачем вторая строчка??? зачем нам еще следующий следующий??

else
begin
while (t^.next^.next<>nil) and ok do
if t^.next^.info=x then
begin
q:=t;
ok:=false;
end
else
t:=t^.Next;

if q<>nil then
begin
T:=Q^.Next;
Q^.Next:=Q^.NEXT^.Next;
T^.Next:=Q^.Next^.Next;
Q^.next^.next:=T;
end;
end;
END;
и здесь тоже зачем нам следующий следующий???




Автор: мисс_граффити 28.05.2007 20:24

Смотри рисунок.
Синим нарисовано, как были расположены указатели, красным - как стали (прошу прощения за качество... интернет почти не работает сегодня, в нормальном не могу выложить. но вроде разобрать можно).Прикрепленное изображение
Q - это элемент перед двумя меняемыми.
T - элемент с ключом х

Номера замен подписаны черным.
То есть 1 - это Q^.Next:=Q^.NEXT^.Next;
2 - T^.Next:=Q^.Next^.Next;
3 - Q^.next^.next:=T;

надеюсь, так разберешься. если что - спрашивай.