Помощь - Поиск - Пользователи - Календарь
Полная версия: сортировка+список
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Rabbit
надо отсортировать список по ключевому признаку, у меня все сортируется но обратно не записывается в список! подскажите где ошибка!
Может чтото с параметрами??


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
Если бы ты во-первых сделал так:
PROCEDURE SORT ( Var FIRST : EL);
, а во-вторых выделал бы память для массивов, в которых собираешься сортировать данные:

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

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

Но утечка памяти все же есть: ты читаешь данные из первоначального списка, не удаляя их из памяти, а потом зачем-то организуешь новый список, т.е., расход памяти увеличивается вдвое... А удалишь ты в конце работы программы - только новый список (если вообще удалишь)...
Rabbit
Спасибо исправила, все работает
а вот еще два кусочка:
тоже не работают
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);

мисс_граффити
1. Основная ошибка у тебя здесь:
            T:=Q;
Q:=Q^.NEXT;
Q^.NEXT:=T; 

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

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

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

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

мисс_граффити
немножко подправила первую (теперь по крайней мере иногда работает):
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
Цитата(мисс_граффити @ 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;

и здесь тоже зачем нам следующий следующий???



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

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

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