AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zerlegesortieren - Probleme (ungültige Zeigeroperation)
Thema durchsuchen
Ansicht
Themen-Optionen

Zerlegesortieren - Probleme (ungültige Zeigeroperation)

Ein Thema von tankm26 · begonnen am 3. Jan 2007 · letzter Beitrag vom 9. Jan 2007
Antwort Antwort
tankm26

Registriert seit: 18. Sep 2004
Ort: Wentorf
87 Beiträge
 
Delphi 7 Personal
 
#1

Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 3. Jan 2007, 20:35
Moin!

Mein Sortieren einer Liste mit dem sogenannten "Zerlege-Sortieren" funktioniert ab bestimmten Längen (ca. >320) nicht mehr. Warum, weiß ich leider nicht. Um allerdings weiterarbeiten zu können (Auswertung der Suchverfahren) bitte ich hier um Hilfe der dp-Comunity.


Der Quellcode:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    btmischen: TButton;
    btauswahl: TButton;
    btende: TButton;
    btaustausch: TButton;
    bteinf: TButton;
    btzerlege: TButton;
    lauswahl: TLabel;
    laustausch: TLabel;
    leinfuege: TLabel;
    ListBox2: TListBox;
    btquicksort: TButton;
    btgeben: TButton;
    lquick: TLabel;
    btmemory: TButton;
    btwiederh: TButton;
    StringGrid1: TStringGrid;
    emax: TEdit;
    btmax: TButton;
    lmax: TLabel;
    btzerlege2: TButton;
    lzereinf: TLabel;
    lzeraus: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure btmischenClick(Sender: TObject);
    procedure btendeClick(Sender: TObject);
    procedure btaustauschClick(Sender: TObject);
    procedure btauswahlClick(Sender: TObject);
    procedure bteinfClick(Sender: TObject);
    procedure btquicksortClick(Sender: TObject);
    procedure btgebenClick(Sender: TObject);
    procedure btmemoryClick(Sender: TObject);
    procedure btwiederhClick(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure btmaxClick(Sender: TObject);
    procedure btzerlege2Click(Sender: TObject);
    procedure btzerlegeClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    procedure schreibediebox;
    procedure zeitmessung(w,s:integer);
    procedure Quick_Sort;
    procedure wimageload;
    procedure maxan(w:integer);
    procedure zerlegesort(ws:integer);
    procedure zMischen;
    procedure zMinimum;
    procedure zeinfuegesort(w,s:integer);
    procedure zauswahlsort(w,s:integer);
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  mPunkt, hilfsliste, nummern,nummernsave: array of Integer;
  karten: array of TBitmap;
  max,AnzahlTeillisten,ss,lt, // für zerlegesort (lt=Länge der Teillisten
  hi,lu,x :integer; //für squicksort
  a,b1,c,b2:int64;

implementation

{$R *.dfm}

procedure tForm1.wimageload;
var w:integer;
begin
  for w:=1 to 33 do begin
    karten[w-1]:=TBitmap.Create;
    karten[w-1].LoadFromFile(IntToStr(w)+'.bmp');
  end;
end;

procedure TForm1.zeitmessung(w,s:integer);
begin
  if w=0 then begin
    QueryPerformanceFrequency(a); //Start
    QueryPerformanceCounter(b1);
  end;
  if w=1 then begin
    QueryPerformanceCounter(b2);
    if s=1 then lauswahl.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
    if s=2 then laustausch.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
    if s=3 then leinfuege.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
    if s=4 then lzereinf.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
    if s=5 then lauswahl.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
    if s=6 then lquick.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
    if s=7 then lzeraus.Caption:=format('Zeit: %g s',[(b2-b1)/a]);
  end;
end;

procedure TForm1.schreibediebox;
var w:integer;
begin
  form1.listbox1.Clear;
  for w:=0 to max-1 do form1.ListBox1.Items.Add(inttostr(nummern[w]));
  stringgrid1.Refresh;
end;

procedure TForm1.maxan(w:integer);
begin
  max:=w;
  Setlength(nummern,max+1);
  SetLength(nummernsave,max);
  SetLength(mPunkt,max);
  SetLength(hilfsliste,max);
  SetLength(karten,max+1);
  for w:=1 to max do
   nummern[w-1]:=w;
  schreibediebox;
  listbox2.Clear;
  form1.btwiederh.Enabled:=false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  maxan(32);
  form1.wimageload;
end;

procedure TForm1.btmischenClick(Sender: TObject);
var w,x,j:integer;
begin
  for w:=0 to max-1 do begin
    j:=Random(max);
    X:=nummern[w];
    nummern[w]:=nummern[j];
    nummern[j]:=x;
  end;
  schreibediebox;
  form1.listbox2.Clear;
  for w:=0 to max-1 do form1.ListBox2.Items.Add(inttostr(nummern[w]));
end;

procedure TForm1.btendeClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.btaustauschClick(Sender: TObject);
var
  ws,i:integer;
  tt: boolean;
begin
// bubble sort
  // Das Feld wird von vorne durchgegangen, die Elemente werden bei Größenunterschied getauscht.
  // Dieses wird solange durchgeführt, bis kein Feld -2 vom Ende aus mehr zu tauschen ist.
  zeitmessung(0,2);
   repeat
     tt:=true;
     for i:=0 to max-2 do begin
       if nummern[i]>nummern[i+1] then begin
         ws:=nummern[i];
         nummern[i]:=nummern[i+1];
         nummern[i+1]:=ws;
         tt:=false;
       end;
     end;
   until tt;
  zeitmessung(1,2);
  schreibediebox;;
end;

procedure TForm1.btauswahlClick(Sender: TObject);
var ws,i,q,a:integer;
begin
 //Auswahlsort.
 //Hier wird, vom Anfang des arrays aus, das jeweils kleinste Element herausgesucht und der unsor-
 //tierten Teilliste hinzugefügt. Dieses wird für jedes Feld bis zum -2. vom Ende aus durchgeführt.
  zeitmessung(0,1);
  for i:=0 to max-2 do begin
    q:=i;
    for ws:=i+1 to max-1 do
     if nummern[ws]<nummern[q] then
      q:=ws;
    a:=nummern[i];
    nummern[i]:=nummern[q];
    nummern[q]:=a;
  end;
  zeitmessung(1,1);
  schreibediebox;
end;

procedure TForm1.bteinfClick(Sender: TObject);
var i,j,x:integer;
begin
  //Einfügesort.
  //Dem sortierten Bereich wird jeweils das 1. Element aus dem unsortierten Teil an der
  //richtigen Stelle hinzugefügt.
  zeitmessung(0,3);
  for i:=1 to max-1 do begin
    x:=nummern[i];
    j:=i-1;
    while (x<nummern[j]) and (j>(-1)) do begin
      nummern[j+1]:=nummern[j];
      dec(j);
    end;
    nummern[j+1]:=x;
  zeitmessung(1,3);
  end;
  schreibediebox;
end;

procedure tForm1.Quick_Sort;
 // Quicksort
  //Das vornehmlich mittlere Feld wird als Referenzwert des unsort. Feldes herausgesucht,
  // suchen uns in Feld links von Referenzwert das erste größere von links aus,
  //entsprechend wird auf der anderen seite verfahren. Dieses Teilen des Feldes wird solange
  //durchgeführt, bis alle Teilfelder "1" lang sind.
 procedure QuickSort(iLo, iHi: Integer);
 var
   Lo, Hi, Mid, T: Integer;
 begin
   Lo := iLo;
   Hi := iHi;
   Mid := nummern[(Lo + Hi) div 2];
   repeat
     while nummern[Lo] < Mid do Inc(Lo);
     while nummern[Hi] > Mid do Dec(Hi);
     if Lo <= Hi then
     begin
       T := nummern[Lo];
       nummern[Lo] := nummern[Hi];
       nummern[Hi] := T;
       Inc(Lo);
       Dec(Hi);
     end;
   until Lo > Hi;
   if Hi > iLo then QuickSort( iLo, Hi);
   if Lo < iHi then QuickSort( Lo, iHi);
 end;

begin
 QuickSort(Low(nummern), High(nummern));
end;

procedure TForm1.zeinfuegesort(w,s:integer);
var i,x,j:integer;
begin
  for i:=w+1 to s do begin
    x:=nummern[i];
    j:=i-1;
    while (x<nummern[j]) and (j>(w-1)) do begin
      nummern[j+1]:=nummern[j];
      dec(j);
    end;
    nummern[j+1]:=x;
  end;
end;

procedure TForm1.zauswahlsort(w,s:integer);
var ws,i,q,a:integer;
begin
  for i:=w to s-1 do begin
    q:=i;
    for ws:=i+1 to s do
     if nummern[ws]<nummern[q] then
      q:=ws;
    a:=nummern[i];
    nummern[i]:=nummern[q];
    nummern[q]:=a;
  end;
end;

procedure TForm1.zerlegesort(ws:integer);
var k,i,NeuAnzahl:integer;
begin
  zeitmessung(0,4);
  lt:=Trunc(2*sqRt(max)); // LÄNGE DER TEILLISTEN bei 1000 = 63
  AnzahlTeillisten:=Trunc(max div lt); //bei 1000 = 15
  if AnzahlTeillisten*lt<max then // 945<1000
   AnzahlTeillisten:=AnzahlTeillisten+1; // 15->16
  NeuAnzahl:=AnzahlTeillisten*lt; // 1008
  for i:=max to NeuAnzahl-1 do // 1000-1007
   nummern[i]:=MaxInt;
  k:=1;
  repeat
    if ws=0 then zeinfuegesort(k-1,k+lt-2); // 1.: 0-62 2.: 63-125 letzter: -1008
    if ws=1 then zauswahlsort(k-1,k+lt-2);
    k:=k+lt;
  until k>=(NeuAnzahl+1);
  zmischen;
  if ws=0 then zeitmessung(1,4);
  if ws=1 then zeitmessung(1,7);
  for i:=0 to max-1 do
   nummern[i]:=hilfsliste[i];
  schreibediebox;
end;

procedure TForm1.zMischen;
var i:integer;
begin
  for i:=0 to AnzahlTeillisten-1 {bei 1000= 0 bis 15} do //Startpositionen für'n Zeiger festlegen
   mPunkt[i]:=i*lt; // an d. erste stelle des jew. teilelementes setzen
  for i:=0 to max-1 do begin
      zminimum;
      hilfsliste[i]:=nummern[mPunkt[ss]];
      mPunkt[ss]:=mPunkt[ss]+1;
  end;
end;

procedure TForm1.zMinimum;
var min,i:integer;
begin
  min:=MaxInt;
  ss:=0;
  for i:=0 to AnzahlTeillisten-1 do
   if mPunkt[i]<=((i+1)*lt-1) then // wenn jeder zeiger noch am Startpunkt ist
    if nummern[mPunkt[i]]<Min then begin // wenn außerdem das an der jeweiligen ersten stelle
                                         //liegende Element kleineer als min ist
      min:=nummern[mPunkt[i]];
      ss:=i;
    end;
end;

procedure TForm1.btquicksortClick(Sender: TObject);
begin
  zeitmessung(0,6);
  Quick_Sort;
  zeitmessung(1,6);
  schreibediebox;
  //stringgrid1.Refresh;
end;

procedure TForm1.btgebenClick(Sender: TObject);
var w:integer;
begin
  for w:=1 to max do begin
    nummern[w-1]:=w;
  end;
  schreibediebox;
end;

procedure TForm1.btmemoryClick(Sender: TObject);
var w:integer;
begin
  for w:=0 to max-1 do nummernsave[w]:=nummern[w];
  form1.btwiederh.Enabled:=true;
end;

procedure TForm1.btwiederhClick(Sender: TObject);
var w:integer;
begin
  for w:=0 to max-1 do nummern[w]:=nummernsave[w];
  schreibediebox;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var w:integer;
begin
  if max=32 then
  for w:=0 to 31 do
   if nummern[Acol]=(w+1) then stringgrid1.Canvas.Draw(rect.left, rect.top, Karten[w]);
end;

procedure TForm1.btmaxClick(Sender: TObject);
begin
  if not (emax.Text='') then begin
  maxan(StrToInt(emax.Text));
  lmax.Caption:=('max= '+(emax.Text));
  end else
  showmessage('Nö! Geben Sie einen gültigen Integerwert ein!');
end;

procedure TForm1.btzerlege2Click(Sender: TObject);
begin
 zerlegesort(1);
end;

procedure TForm1.btzerlegeClick(Sender: TObject);
begin
  zerlegesort(0);
end;

end.

fürs Zerlegesort:
Länge der liste: n (4/n soll "glatt" möglich sein) bei mir zur besseren ÜPbersichtlichkeit max

Anzhl Teillisten: t:=4 bei mir zur besseren ÜPbersichtlichkeit "anzahlteillisten"

Länge der Teillisten: lt

Hilfsliste: (sortierte Liste)

Zeigerstellungsarray: mPunkt: array
mfg


Wieland Sommer
Angehängte Dateien
Dateityp: zip sortierverfahren_pascal_funzt_3_113.zip (377,3 KB, 4x aufgerufen)
Wieland S.
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 3. Jan 2007, 21:38
Wo steigt denn Dein Sortierverfahren aus, schon mal mit Breakpoints (bedingten) versucht näheres herauszufinden?

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
tankm26

Registriert seit: 18. Sep 2004
Ort: Wentorf
87 Beiträge
 
Delphi 7 Personal
 
#3

Re: Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 4. Jan 2007, 11:33
Wo zeigt es nicht an - was bedingte Pausen sind weiß ich (noch) nicht - und bislang habe ich eher verscuht, den code einfach nur teilweise zu implementieren. Na, ich setz' mich jetzt nochmal daran.



edit: Komischerweise funktioniert es jetzt, ohne dass ich etwas verändert hätte, sogar noch bei 100000 - und auch bei beliebigen Werten <100000 (3200,4567,10000,...).

Das Sortieren dauert bei den einigermaßen effizienten noch immer weniger als ne sekunde, doch das Übertragen in die listbox ein vielfaches länger.

Vielen Dank für Ihre (deine) Mühe, Klaus01!
Wieland S.
  Mit Zitat antworten Zitat
tankm26

Registriert seit: 18. Sep 2004
Ort: Wentorf
87 Beiträge
 
Delphi 7 Personal
 
#4

Re: Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 4. Jan 2007, 17:20
So, da bin ich wieder..

Gerne würde ich jetzt einen Mauszeiger einfügen, der eine Sanduhr beinhaltet, solange das Programm sortiert. Warum funktioniert meine Idee nicht?




Delphi-Quellcode:
procedure TForm1.btaustauschClick(Sender: TObject);
var
  ws,i:integer;
  tt: boolean;
begin
// bubble sort
  // Das Feld wird von vorne durchgegangen, die Elemente werden bei Größenunterschied getauscht.
  // Dieses wird solange durchgeführt, bis kein Feld -2 vom Ende aus mehr zu tauschen ist.
 mausae(0);
zeitmessung(0,2);
   repeat
     tt:=true;
     for i:=0 to max-2 do begin
       if nummern[i]>nummern[i+1] then begin
         ws:=nummern[i];
         nummern[i]:=nummern[i+1];
         nummern[i+1]:=ws;
         tt:=false;
       end;
     end;
   until tt;
  zeitmessung(1,2);
  schreibediebox;;
end;

procedure TForm1.mausae(ws:integer);
begin
  if ws=0 then begin
    btaustausch.Cursor:=crAppStart;
    Form1.Cursor:=crAppStart;
  end;
  if ws=1 then begin
    Form1.Cursor:=crDefault;
    btaustausch.Cursor:=crDefault;
  end;
end;

procedure TForm1.schreibediebox;
var w:integer;
begin
  form1.listbox1.Clear;
  for w:=0 to max-1 do
   form1.ListBox1.Items.Add(inttostr(nummern[w]));
  stringgrid1.Refresh;
  mausae(1);
end;
Wieland S.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#5

Re: Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 4. Jan 2007, 17:37
Hallo Wieland,

nur ein paar Kommentare zu einem Ausschnitt deines Codes:

Delphi-Quellcode:
procedure TForm1.SchreibeDieBox;
var
  i: Integer;
begin
  // Form1.ListBox1.Clear;
  // innerhalb einer Methode besser nie mit dem Namen der
  // Form-Variablen qualifizieren.
  with ListBox do
  begin
    Items.BeginUpdate; // beschleunigt ungemein
    Clear;
    for i := 0 to High(nummern) do
       Items.Add( IntToStr(nummern[i]) );
    Items.EndUpdate;
  // stringgrid1.Refresh; // hat hier nix verloren
  // mausae(1); // gehört auf die gleiche Code-Ebene wie mausae(0)
end;
Grüße vom marabu
  Mit Zitat antworten Zitat
tankm26

Registriert seit: 18. Sep 2004
Ort: Wentorf
87 Beiträge
 
Delphi 7 Personal
 
#6

Sortierprogramm

  Alt 5. Jan 2007, 10:15
Moin!

Vielen Dank für Ihre Hilfe, das Aktualisieren der listbox geht jetzt wirklich bltzschnell.

Das Programm habe ich der Übersicht halber in zwei units aufgeteilt, die Suchverfahren haben nun eine eigene.

Was meinen Sie mit "selber Ebene"? Die procedure, in welcher auch mausae(0) aufgerufen wird?


Irgendetwas zwickt noch, sodass bei einer Länge der Liste von 3200 und 25 Durchgängen beim Wiederherstellen der unsortierten Liste plötzlich die Felder von zerlegen drin sind.

edit: Auch das habe ich erledit. Wie würdet ihr da Rechne des Computers dem Nutzer zum Ausdruck bringen? Mittels einer Sanduhr? Und wie könnte man das Programm komplett stillegen?
Angehängte Dateien
Dateityp: rar sortierverfahren_pascal_funzt_4_200.rar (327,9 KB, 2x aufgerufen)
Dateityp: rar sortierverfahren_mit_x-facher_durchf_hrung_214.rar (329,2 KB, 1x aufgerufen)
Wieland S.
  Mit Zitat antworten Zitat
tankm26

Registriert seit: 18. Sep 2004
Ort: Wentorf
87 Beiträge
 
Delphi 7 Personal
 
#7

Re: Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 8. Jan 2007, 22:03
Moin!

Inzwischen bin ich wieder ein ganzes Stück weiter, stoße jetzt aber auf ein erstaunliches Problem:

Die Zeitmessung, für die Ermittlung der Effektivität unerlässlixh, funktioniert nicht merh. Worann kann das liegen?

neu:
Delphi-Quellcode:
var
  a,b1,c,b2:int64;
  qq: single;



implementation
uses unit1;

procedure zeitmessung(w,s,o:integer);
begin
  if w=0 then begin
    QueryPerformanceFrequency(a); //Start
    QueryPerformanceCounter(b1);
  end;
  if w=1 then begin
    QueryPerformanceCounter(b2);
    qq:=qq+( (b2-b1) /a);
    if o=1 then begin
      if s=1 then unit1.Form1.lauswahl.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=2 then unit1.Form1.laustausch.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=3 then unit1.Form1.leinfuege.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=4 then unit1.Form1.lzereinf.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=5 then unit1.Form1.lzeraus.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=6 then unit1.Form1.lquick.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
    end;
  end;
end;

procedure auswahlsort;
var ws,i,q,a:integer;
begin
  zeitmessung(0,1,0); //starte zeitmessung
 //mausae(0);
 //Auswahlsort.
 //Hier wird, vom Anfang des arrays aus, das jeweils kleinste Element herausgesucht und der unsor-
 //tierten Teilliste hinzugefügt. Dieses wird für jedes Feld bis zum -2. vom Ende aus durchgeführt.
  for i:=0 to max-2 do begin
    q:=i;
    for ws:=i+1 to max-1 do
     if nummern[ws]<nummern[q] then
      q:=ws;
    a:=nummern[i];
    nummern[i]:=nummern[q];
    nummern[q]:=a;
  end;
  zeitmessung(1,1,0); //stope zeitmessung
end;
alt:
Delphi-Quellcode:
//unit1:
var
  Form1: TForm1;
  werte,mPunkt, hilfsliste, nummern,nummernsave: array of Integer;
  karten: array of TBitmap;
  max,anzahldurch, AnzahlTeillisten,ss,lt, // für zerlegesort (lt=Länge der Teillisten
  hi,lu,x :integer; //für squicksort
  a,b1,c,b2:int64;
  qq: extended;

implementation

{$R *.dfm}

procedure tForm1.wimageload;
var w:integer;
begin
  for w:=1 to 33 do begin
    karten[w-1]:=TBitmap.Create;
    karten[w-1].LoadFromFile(IntToStr(w)+'.bmp');
  end;
end;

procedure TForm1.zeitmessung(w,s,o:integer);
begin
  if w=0 then begin
    QueryPerformanceFrequency(a); //Start
    QueryPerformanceCounter(b1);
  end;
  if w=1 then begin
    QueryPerformanceCounter(b2);
    qq:=qq+( (b2-b1) /a);
    if o=1 then begin
      if s=1 then lauswahl.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=2 then laustausch.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=3 then leinfuege.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=4 then lzereinf.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=5 then lzeraus.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
      if s=6 then lquick.Caption:=format('Zeit: %g s',[qq/anzahldurch]);
    end;
  end;
end;



//unit2:
procedure auswahlsort;
var ws,i,q,a:integer;
begin
  unit1.Form1.zeitmessung(0,1,0); //starte zeitmessung
 //mausae(0);
 //Auswahlsort.
 //Hier wird, vom Anfang des arrays aus, das jeweils kleinste Element herausgesucht und der unsor-
 //tierten Teilliste hinzugefügt. Dieses wird für jedes Feld bis zum -2. vom Ende aus durchgeführt.
  for i:=0 to max-2 do begin
    q:=i;
    for ws:=i+1 to max-1 do
     if nummern[ws]<nummern[q] then
      q:=ws;
    a:=nummern[i];
    nummern[i]:=nummern[q];
    nummern[q]:=a;
  end;
  unit1.Form1.zeitmessung(1,1,0); //stope zeitmessung
end;
Angehängte Dateien
Dateityp: rar sortierverfahren_mit_grafik_0.6_394.rar (353,3 KB, 2x aufgerufen)
Dateityp: rar sortierverfahren_mit_grafik_0.1_941.rar (336,2 KB, 1x aufgerufen)
Wieland S.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#8

Re: Sortierprogramm

  Alt 9. Jan 2007, 07:55
Hallo Wieland,

Zitat von tankm26:
... Was meinen Sie mit "selber Ebene"? Die procedure, in welcher auch mausae(0) aufgerufen wird? ...
den Hinweis mit der Aufrufebene hast du genau richtig verstanden und, wie ich an deinem Code sehen kann, auch so umgesetzt.

Zitat von tankm26:
... Die Zeitmessung, für die Ermittlung der Effektivität unerlässlixh, funktioniert nicht merh. Worann kann das liegen? ...
Deine globalen Variablen werden im Hauptspeicher in der von dir angegebenen Ordnung aufeinander folgend angelegt.

Delphi-Quellcode:
var
  // ...
  ergebnisse: array [0..4, 0..3] of Single;
  max, anzahldurch, AnzahlTeillisten, ss, lt, hi, lu, x: Integer;
Dein Array ergebnisse[] besteht aus 20 Elementen, die zweidimensional adressiert werden. Im Ereignis-Code OnCreate() deiner Form initialisierst du die Variable anzahldurch:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  // ...
  anzahldurch := 25;
  maxan(32);
  // ...
end;
Der Aufruf der Methode maxan() führt dann zur kleinen Katastrophe:

Delphi-Quellcode:
procedure TForm1.maxan(w: Integer);
var
  i, s: Integer;
begin
  for i := 0 to 6 do
    for s := 1 to 3 do
      ergebnisse[i, s] := 0;
Bei der Initialisierung gehst du von 28 Elementen aus, sieben in der ersten Dimension und vier in der zweiten. Die Typen Single und Integer belegen jeweils ein Doppelwort (vier Byte), sodass folgendes passiert: Du initialisierst 28 Doppelworte mit 0, außer dem ersten, dem fünften, dem neunten, etc. (weil du in der zweiten Dimension mit eins und nicht mit 0 startest). Da du acht Doppelworte zuviel adressierst, werden auch noch die folgenden Integer-Variablen mit 0 initialisiert, außer max und lt. Führe Konstanten für die statische Dimensionierung ein, oder benutze die eingebauten Funktionen High() und Low() beim Zugriff auf Arrays.

Ich fürchte, dass da noch einige Fehler in deinem Code stecken. Die vielen globalen Variablen machen, nicht zuletzt durch ihre wenig sprechenden Namen, einen Code-Walk-Through nicht gerade leicht. Falsche oder fehlende Initialisierungen globaler Variablen sind auch der Grund für die Division durch 0 beim ersten Aufruf der Methode zeitmessung().

Freundliche Grüße
  Mit Zitat antworten Zitat
tankm26

Registriert seit: 18. Sep 2004
Ort: Wentorf
87 Beiträge
 
Delphi 7 Personal
 
#9

Re: Zerlegesortieren - Probleme (ungültige Zeigeroperation)

  Alt 9. Jan 2007, 08:32
Moin!


Vielen Dank für die Tips, jetzt geht's erstmal ab zur Schule. Heute nachmittag sehe ich weiter!

edit: Ein wenig Zeit habe ich noch....so, jetzt habe ich auch verstanden, wo der Fehler lag. "Mein" Ergebnissarrray war zu kurz! Gut, dass habe ich geändert. Jetzt werden die Variablen mal logischer benannt.
Nocheinmal: Es war sehr nett, dass Sie mir so schnell geholfen haben!
Wieland S.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz