Immer noch arbeite ich an und mit einem DOS-Programm, erstellt mit Turbo-Pascal 7.0. (Leider kenne ich nichts, was eine Umstellung auf Windows (Delphi) halbwegs automatisch ermöglicht.)
Auf meinem neuen Computer (Windows XP Prof.) stelle ich nun fest, dass Sortier-Ergebnisse, Ablauf mit denselben Daten auf demselben Weg, von einander abweichen: Mal sind sie in Ordnung, mal ist die Sortierung fehlerhaft. Kann die Ursache dafür sein, dass der Computer wegen seiner höheren Geschwindigkeit die Ursache dafür ist? Wenn ja: Wie kann ich diese für DOS-Programme drosseln? Oder wo kann die Ursache sonst liegen?
Für Hilfe wäre ich sehr dankbar.
Programmieren - alles kontrollieren 4.937 Themen, 20.662 Beiträge
Hi!
Diese Funktion ist eine von elf ähnlichen Vergleichs-Funktionen, die unterschiedliche Records bearbeiten, aber alle aus der Baum-Unit aufgerufen werden. Vorher bekommt die Baum-Unit (im Beispiel unten rsBptr) vom Hauptprogramm als Parameter den zu bearbeitenden Datensatz zugewiesen (ispieler) sowie die far-Adresse der Vergleichs-Funktion (VglRS), die zu verwenden ist, und falls erforderlich die Datensatzlänge (SizeOf).
Das ist C-Programmierstil. ;-)
Ich hätte dazu eine Objektstruktur erstellt, welche eine Basisklasse verwendet und dann für die 11 Records 11 abgeleitete Objektklassen verwendet. Die Funktionen oder Methoden, die mit all den 11 Typen arbeiten müssen, erwarten dann als Parameter einen Zeiger der Basisklasse.
Die Vergleichsmethode wird dann virtuell deklariert und in der jeweiligen Klasse implementiert.
Ich vermeide einfach Typkonvertierungen und untypisierte Pointer, soweit ich das kann. Diese IMHO C-typischen Operationen waren mir nie ganz geheuer. Ich finde, da verliert man zu schnell bei Änderungen die interne Datenintegrität.
> Wie genau arbeitet deine Sortierung?
Diese Frage verstehe ich leider nicht. Ihre Aufgabe ist es, die Datensätze genau in die Reihenfolge zu bringen, die durch das aktuelle Datenfeld bestimmt wird.
Ich wollte, dass du beschreibst, wie du deine Knoten-Elemente sortierst, also wie der programmierte Algorithmus abläuft. (Geklärt; siehe Unten)
Die Funktion musste ich mir etwas anders Formatieren, damit ich den Ablauf verstehe. Vermutlich fehlen Ungleichs im Quelltext, weil Nickles.de die gefiltert hat. (Kommentare sind von mir.)
procedure InsVar (var baum5: p_baum_u; var v0; siz0: integer;KleinF: FuncKlein; var okay9: byte);
{fügt die Variable v0 mit der Größe siz0 Bytes in den Baum ein -
bei Gleichheit wird der bestehende Eintrag überschrieben
okay9 = 0, wenn Variable v0 eingefügt
1, wenn bestehender Eintrag überschrieben
2, wenn Speicherplatz nicht ausreicht}
var pk1, pk2 : pKnoten;
dir : (l, r); {Suchrichtung für Einfügestelle}
pv : ^t_objekt; {das ist jetzt ein Objekt und nicht pointer? inhalt ist auch so deklariert?}
procedure NewNode (var B_neu: pKnoten; last: p_baum_u); {wieso ist last nicht vom Typ pKnoten? Unten wird da pk2 zugewiesen.}
var pk1 : pKnoten;
begin
if MaxAvail 1 then Exit;
New (pk1);
with pk1^ do
begin
size := siz0; left := nil; right := nil; back := last;
GetMem (inhalt, size); Move (v0, inhalt^, size);
end {with};
B_neu := pk1;
end; {NewNode}
begin {InsVar}
pk1 := pKnoten (baum5); pk2 := pk1; pv := @v0; okay9 := 0;
while pk1 nil do {schluckt Nickles.de hier das ungleich?}
with pk1^ do
begin
pk2 := pk1; {aktueller Node in pk2 speichern}
{im aktuellen Element bestimmen, ob der neue Node Links oder Rechts eingefügt werden muss.}
if KleinF (pv, inhalt) then {ich vermute pk1.inhalt wäre korrekt, oder?}
begin
{pv ist kleiner als der aktuelle Node, also linkes Element als nächstes nehmen}
dir := l; pk1 := left;
end
else
begin {ich wars}
{pv war nicht kleiner}
if KleinF (inhalt, pv) then
begin
{pk1.inhalt ist kleiner als pv (Prüfung erfolgt eigentlich um Gleichheit festzustellen)
also rechten Node nehmen}
dir := r; pk1 := right;
end
else
begin
{pk1.inhalt und pv sind gleich, also überschreiben}
if pk1^.size siz0 then Writeln ('TYPE MISMATCH ERROR!')
else Move (v0, inhalt^, size);
okay9 := 1;
Exit; {Funktion verlassen}
end {else};
end; {ich wars}
end {while/eigentlich with};
{while endet hier}
NewNode (pk1, pk2);
if okay9 > 1 then Exit;
if pk2 nil then
{Abhängig vom letzten Suchschritt neuen Node in zuletzt beim Suchlauf gefundenen Node eintragen
Bei Gleichheit wurde Funktion bereits beendet.}
if dir = l then pk2^.left := pk1
else pk2^.right := pk1
else
{Sonderfall: erster Node in Baum}
baum5 := pk1;
end; {InsVar}
Baum5 scheint ein Zeiger auf den ersten Node der Baumstruktur zu sein, wird mit einem Wert vom Typ pknoten belegt, ist aber vom Typ p_baum_u.
Durch die Analyse der Funktion habe ich verstanden, wie dein Sortieren funktioniert. Du baust einen sortierten Baum auf. OK. Grundsätzlich funktioniert das und obwohl ich die ganze Typenbehandlung in deinen Sourcen nicht mag ;-) , kann ich keinen Grund finden, warum die Routine falsch arbeiten sollte.
Der Baum muss aber noch ausgegeben werden. Vielleicht liegt das Problem an der Stelle. Wie wird die Liste der gespeicherten daten aus dem Baum ausgelesen?
Bis dann
Andreas