Sortowanie listy jednokierunkowej - Lazarus

0

Witam. Czy mógłby ktoś zerknąć dlaczego kod nie działa? Dodawanie elementów do listy chodzi dobrze ale jest problem z sortowaniem. Już dwa tygodnie nad tym siedzę dlatego proszę o pomoc. Podejrzewam ze jest problem w procedurze NowyNastepny. Jeśli tak to czy ma ktoś pomysł jak to zmienić? Z góry dziękuje za pomoc.

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Windows, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Koniec: TButton;
    Info: TButton;
    Sortuj: TButton;
    Losuj: TButton;
    Label1: TLabel;
    Lista: TLabel;
    ListBox1: TListBox;
    ListBox2: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure InfoClick(Sender: TObject);
    procedure KoniecClick(Sender: TObject);
    procedure LosujClick(Sender: TObject);
    procedure SortujClick(Sender: TObject);

  private


  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }
  type

    tWezel = record
      x: integer;
      Nastepny: ^tWezel;
    end;
    tPWezel = ^tWezel;

    var
      Wezel: ^tWezel;
      Wezel2: ^tWezel;
      Wezel3: ^tWezel;
      WezelN2: ^tWezel;
      WezelN4: ^tWezel;
      Wezel_Pierwszy: ^tWezel;
      WezelNowy: ^tWezel;
      WezelN2_Pierwszy: ^tWezel;
      Wezel_Koniec: ^tWezel;
      Nowy: ^tWezel;

      x,i,: integer;

procedure NowyNastepny;
begin
   if Wezel<>nil then begin
  new(WezelN2);
  WezelN2^.x:=Wezel2^.x;
  WezelNowy^.Nastepny:=Wezel^.Nastepny;
  Wezel^.Nastepny:=WezelN2;
  end;

end;

procedure NowyOstatni;
begin
  if Wezel^.Nastepny=nil then begin
  new(WezelN2);
  WezelN2^.x:=Wezel2^.x;
  WezelN2^.Nastepny:=nil;
  Wezel^.Nastepny:=WezelN2;
end;

end;


procedure Usun;
begin
 while Wezel <> nil do
 if Wezel2 = Wezel_Pierwszy then begin 
 Wezel:=Wezel_Pierwszy;
 Wezel_Pierwszy:=Wezel_Pierwszy^.Nastepny;
 dispose(Wezel);
  Wezel:=Wezel_Pierwszy;
  exit;
  end else begin
  Wezel3^.Nastepny:=Wezel2^.Nastepny;
  dispose(Wezel2);
  Wezel:=Wezel_Pierwszy;
  exit;
  end;
end;


function Szukaj(Wezel: tPWezel; x: integer): tPWezel;

  begin
   Wezel:=Wezel_Pierwszy;
   new(Wezel2);
  new(Wezel3);
  while Wezel <> nil do
  begin
     if Wezel=Wezel_Pierwszy then begin
     Wezel2:=Wezel;
     Wezel:=Wezel^.Nastepny;
     if Wezel^.x<Wezel2^.x then
     begin
     Szukaj:=Wezel;
     NowyNastepny;
     Usun;
     exit;
     end;
     end else begin
     if Wezel^.x<Wezel2^.x then
     begin
     Szukaj:=Wezel;
     NowyNastepny;
     Usun;
     exit;
     end;
     end;
     Wezel3:=Wezel2;
     Wezel2:=Wezel;
     Wezel:=Wezel^.Nastepny;
     end;
  Szukaj:=nil;
end;


procedure TForm1.LosujClick(Sender: TObject);
begin
  if Wezel=nil then begin
  new(Wezel_Pierwszy);
  new(Wezel);
  Wezel_Pierwszy:=Wezel;
  i:=1;
  randomize;
  Wezel^.x:=random(100);
  ListBox1.Items.Add(IntToStr(i)+'  '+IntToStr(Wezel^.x));
  end
  else begin
  while Wezel^.Nastepny <> nil do Wezel:=Wezel^.Nastepny;
  new(WezelNowy);
  randomize;
  WezelNowy^.x:=random(100);
  i:=i+1;
  ListBox1.Items.Add(IntToStr(i)+'  '+IntToStr(WezelNowy^.x));
  WezelNowy^.Nastepny:=nil;
  Wezel^.Nastepny:=WezelNowy;
end;
end;





procedure TForm1.SortujClick(Sender: TObject);

 begin
  Szukaj(Wezel,x);
   Wezel:=Wezel_Pierwszy;
  while Wezel <> nil do begin
  ListBox2.Items.Add(IntToStr(Wezel^.x));
  Wezel:=Wezel^.Nastepny;
  end;
end;


procedure TForm1.KoniecClick(Sender: TObject);
begin
  Application.Terminate
end;
1
  • po pierwsze, fatalne, a w właściwie to brak formatowania, co utrudnia czytanie kodu
  • po drugie, zmienne globalne które w procedurach i metodach pełnią funkcje zmiennych lokalnych
  • po trzecie, zupełnie nie wiadomo co ma robić metoda TForm1.SortujClick(Sender: TObject); o którą jak sądzę pyta autor.
  • po czwarte, błędy syntaktyczne, np. w linii 65 przecinek po zmiennej i przed średnikiem
  • po piąte , pomieszanie z poplątaniem ze zmiennymi, nie wiadomo która za co odpowiada, niezainicjowane zmienne w procedurach ...
    Np. wywołanie procedury Szukaj(Wezel,x); w pierwszym wierszu metody TForm1.SortujClick(Sender: TObject);. Co siedzi w Wezel oraz x ???

W sumie kod do totalnej poprawy. Myślę że nikt na forum nie będzie tego analizował.

2

Znowu powtarzany jest ten sam potężny błąd, czyli implementowanie listy w zdarzeniach komponentów, zamiast w formie osobnych procedur/funkcji, niezależnych od interfejsu. W ten sposób straszny bajzel powstaje i trudno nad takim kodem zapanować, a już szczególnie, kiedy używa się mnóstwa zmiennych globalnych.

Zobacz sobie na moją odpowiedź w ostatnim wątku dotyczącym list — masz tam wskazówki na temat tego, jak zabrać się za implementację. Co prawda tam jest mowa o liście dwukierunkowej, ale zasady pozostają te same.

0

Dzięki. Już sobie poradziłem.

0

@przemoStudent:

Dzięki. Już sobie poradziłem.

jeśli rozwiązałeś problem to pokaż w jaki sposób

1 użytkowników online, w tym zalogowanych: 0, gości: 1