Sortowanie listy jednokierunkowej - Lazarus

Sortowanie listy jednokierunkowej - Lazarus
PS
  • Rejestracja:ponad 3 lata
  • Ostatnio:ponad 3 lata
  • Postów:2
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.

Kopiuj
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;
edytowany 2x, ostatnio: cerrato
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:minuta
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ł.

edytowany 3x, ostatnio: grzegorz_so
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:17 minut
  • Lokalizacja:Tuchów
  • Postów:12175
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.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 2x, ostatnio: flowCRANE
GS
@furious programming: błędem jest implementowanie nie tylko listy ale również jakiejkolwiek innej ważnej logiki. Myślę że autor postu amatorsko uczy się programowania
flowCRANE
To raczej zadanko na studia, więc nie dziwię się, że tak ludzie kod piszą, skoro najwyraźniej nikt nie ich pisać kodu poprawnie.
GS
@furious programming: tak może być a problem listy jest w skrócie "szkolny". Ale nie sądzę aby na studiach uczono tak fatalnych zasad programowania
flowCRANE
IMO tu nie chodzi o uczenie złych praktyk, a o nie uczenie tych dobrych. Czyli w skrócie, o pozostawienie studentów samych sobie, niech sami wymyślą jak napisać kod w aplikacji obiektowej, tu okienkowej. Dla niedoświadczonego kodera, wygenerowanie zdarzeń i implementacja w nich logiki wydaje się naturalnym i intuicyjnym podejściem.
GS
Klikając okienkowo łatwo iść na skróty i umieszczać kod w oclick. Sam nieraz tak robię, ale tylko w przypadku prostych, testowych projektów, kiedy chcę szybko przetestować jakiś prosty kod nie bawiąc się w OOP
PS
  • Rejestracja:ponad 3 lata
  • Ostatnio:ponad 3 lata
  • Postów:2
0

Dzięki. Już sobie poradziłem.

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:minuta
0

@przemoStudent:

Dzięki. Już sobie poradziłem.

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

edytowany 2x, ostatnio: grzegorz_so

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.