Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.09.2011, 11:05   #1
pobedin
Форумчанин
 
Регистрация: 30.07.2009
Сообщений: 105
По умолчанию Список. Сортировка.

Здравствуйте. Сортирую список, но ничего не происходит. В чем мб причина?
p.s. number представлен как integer;
Код:
procedure TfrmMain.SortList;
var
  tmp, tmps: TPList;
begin
  curr := head;
  while curr <> nil do
  begin
    tmp := curr^.next;
    while tmp <> nil do
    begin
      if tmp^.number < curr^.number then
      begin
        tmps := tmp;
        tmp := curr;
        curr := tmps
      end;
      tmp := tmp^.next
    end;
    curr := curr^.next
  end;
end;
pobedin вне форума Ответить с цитированием
Старый 09.09.2011, 14:28   #2
Step_UA
Форумчанин
 
Аватар для Step_UA
 
Регистрация: 09.06.2011
Сообщений: 388
По умолчанию

Вам необходимо обменивать значение поля Number в списке, а не указатели
Код:
var i:integer;
       . . .
if tmp^.number < curr^.number then
   begin
    i := tmp^.number; 
    tmp ^.number:= curr^.number;
    curr^.number := i
   end;
на неконкретные вопросы даю неконкретные ответы ...
Step_UA вне форума Ответить с цитированием
Старый 09.09.2011, 14:44   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Вам необходимо обменивать значение поля Number в списке, а не указатели
Это было хорошо и правильно, если бы в структуре не было больше других полей!

вот у автора в другой теме описание структур:
Цитата:
Код:
type
  TPList = ^TList; //указатель на тип

  TList = record
    name: string[20];
    number: string[20];
    value: string[10];
    typeProd: string[10];
    color: string[10];
    next: TPList; // следующий элемент списка
  end;
очевидно, что поменять местами только Number приведёт к хаосу и разброду остальных полей.

pobedin, для сортировки списка нужно не обменивать записи местами, а корректировать указатели так, чтобы записи физически остались на своих местах, а вот их позиции в списке поменялись.

p.s. если не разберётесь самостоятельно и попозже будет у меня время - набросаю примерчик-иллюстрацию...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.09.2011, 14:49   #4
pobedin
Форумчанин
 
Регистрация: 30.07.2009
Сообщений: 105
По умолчанию

завтра сдавать курсовую, так что к этому времени видимо не разберусь. еще много работы. если позже напишите пример, буду признателен.
pobedin вне форума Ответить с цитированием
Старый 09.09.2011, 15:16   #5
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

вводим еще 4 переменные
Код:
prevcurr, prevtmp, nextcurr, nexttmp: TPList;
задаем их значения так чтобы они указывали на соседей (впереди prev и после -next) наших записей (curr, tmp). их заполнение остается тебе.
И меняем ссылки в списке
Код:
prevcurr.next:=tmp;
tmp.next:=nextcurr; // поставили tmp на место curr 
prevtmp.next:=curr;
curr..next:=nexttmp; // поставили curr на место tmp

curr:=prevcurr.next;// теперь меняем сами curr (просто берем новую ссылку из предыдущего)
tmp;=prevtmp.next; //тоже для rmp
если подумать можно обойтись меньшим число переменных.
и конечно надо будет учесть что curr и tmp могут быт в начале/конце списка. что-то вроде
curr=hard / prevcurr=nil
tmp.next =nil / nexttmp =nil

сам цикл будет вроде этого
Код:
//  curr := head;
  prevcurr:=nil;
  if prevcurr=nil then curr:=head else curr:=prevcurr.next;
  while curr <> nil do
  begin
     prevtmp:=curr;
     tmp := prevtmo.next;
    while tmp <> nil do
       if tmp.number <>curr.number then begin
// а prevcurr и prevtmp уже есть
// так что меняем как написано выше (нее забыв про nextcurr nexttmp)
       end;
//      tmp := tmp^.next
      prevtmp:=tmp;
     tmp := prevtmo.next;
    end;
//    curr := curr^.next
     prevcurr:=curr;
     curr:=prevcurr.next;
end;
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 09.09.2011 в 15:33.
evg_m на форуме Ответить с цитированием
Старый 09.09.2011, 15:35   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
завтра сдавать курсовую
ок. Если Вам главное, чтобы сортировка работала (неважно, оптимально Вы сделали так, как положено - меняя указатели, или, неоптимально, меняя полностью информационное наполнение) тогда можете попробовать такой код (это второй вариант - неоптимальный):

Код:
procedure TfrmMain.SortList;
var
  curr: TPList;
  tmp, tmps: Tlist;
  Link1, Link2: TPList;
  wasChange: boolean;
begin
  wasChange := false;
  repeat
    curr := head;
    while curr <> nil do
    begin
      if curr^.Next <> nil then begin
        tmp := curr^.Next^;
        if tmp.number < curr^.number then
        begin
          Link1 := tmp.Next;
          Link2 := curr^.Next;
          tmps := tmp;
          tmp := curr^;
          curr^ := tmps;
          tmp.Next := Link1;
          curr^.Next := Link2;
          wasChange := true;
        end;
      end;
      curr := curr^.next
    end;
  until not wasChange;
end;
p.s. код на работоспособность я не проверял, поэтому за правильность НЕ ПОРУЧУСЬ...

p.p.s. вечером постараюсь написать правильный вариант
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.09.2011, 15:53   #7
pobedin
Форумчанин
 
Регистрация: 30.07.2009
Сообщений: 105
По умолчанию

спасибо. вечером попробую и отпишу работоспособность
pobedin вне форума Ответить с цитированием
Старый 09.09.2011, 16:07   #8
Step_UA
Форумчанин
 
Аватар для Step_UA
 
Регистрация: 09.06.2011
Сообщений: 388
По умолчанию

Цитата:
Это было хорошо и правильно, если бы в структуре не было больше других полей!
Ну не получится с меня телепата ...
тогда с корректировкой указателей:
Код:
procedure TfrmMain.SortList;
var
  p_curr,p_tmp,tmp, p_min,min: TPList;
begin
  curr := head; 
  while curr^.next <> nil do
  begin
    p_tmp := curr;
    tmp:=curr^.next;
    min:=curr;
    while tmp <> nil do
    begin
      if tmp^.number < min^.number then
       begin
        min:=tmp;
        p_min:=p_tmp
       end;
       p_tmp:=tmp;
       tmp:=tmp^.next;
     end; 
    if curr<>min tnen
     begin
      if curr=head then head:=min
            else p_curr^.next:=min
      p_min^.next:=curr;
      tmp:=curr^.next;
      curr^.next:=min^.next;
      min^.next:=tmp;
      p_curr:=min
     end
     else p_curr:=curr;
   curr := p_curr^.next
  end;
end;
на неконкретные вопросы даю неконкретные ответы ...
Step_UA вне форума Ответить с цитированием
Старый 09.09.2011, 23:32   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

1) мой пример кода из пост #6 - кривой и не работает!
его абсолютно несложно исправить
Код:
procedure TfrmMain.SortListBad;
var
  curr: TPList;
  tmps : Tlist;
  tmp : TPList;
  Link1, Link2: TPList;
  wasChange: boolean;
begin
  repeat
    curr := head;
    wasChange := false;
    while curr <> nil do
    begin
      if curr^.Next <> nil then begin
        tmp := curr^.Next;
        if tmp^.number < curr^.number then
        begin
          Link1 := tmp^.Next;
          Link2 := curr^.Next;
          tmps := tmp^;
          tmp^ := curr^;
          curr^ := tmps;
          tmp^.Next := Link1;
          curr^.Next := Link2;
          wasChange := true;
        end;
      end;
      curr := curr^.next
    end;
  until not wasChange;
end;
но не вижу смысла его использовать, если есть рабочий вариант от Step_UA (смотри замечание ниже)


2) то, что писал evg_m в пост #5 - абсолютно в точку. я об этом и пытался сказать...

3) код Step_UA я проверил. всё работает.
(только есть пара мелких опечаток: tnen и точки с запятой не хватает,
вот исправленный кусочек кода:
Цитата:
Код:
    if curr <> min then
    begin
      if curr = head then head := min
      else p_curr^.next := min;

Последний раз редактировалось Serge_Bliznykov; 09.09.2011 в 23:37.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Список с заглавным звеном, из текстового файла получить список из записей и по нему уже сделать задание Zigfried Помощь студентам 2 04.10.2010 20:29
Сортировка слиянием(1 сорт список+2 сорт список=3 сорт список) Promolol Помощь студентам 0 21.05.2010 23:49
[C++] Челночная сортировка / Список xXxGrafffxXx Общие вопросы C/C++ 24 17.06.2009 00:18
Список. Сортировка werser Помощь студентам 1 28.05.2009 02:20