![]() |
Doppelt verkettete Liste sortieren
Huhu ich bins mal wieder.
Ich habe ein kleines Problem. und zwar habe ich eine Doppelt verkettete Liste of einfach verkettete Liste Diese Doppelt verkettete Liste möchte ich nun gerne sortieren und zwar nach der Länge der einfach verketteten Listen. Dazu haben die einfachen Listen eine
Delphi-Quellcode:
Nun Suche ich einen geeigneten Algorithmus.
Function GetAnzahl(Anker:Tliste):integer;
Anforderungen:
Um Fragen vorzubeugen warum ich kein Array of Liste nehme: Laufzeit mir Array: 2h Laufzeit mit Liste: 3 min Pointer umhängen ist nunmal einfach schneller ;) Habe schon gegoogelt, aber entweder ich bin zu Dumm, oder es hatte noch niemand dieses Problem^^ Mfg Noobinator |
Re: Doppelt verkettete Liste sortieren
Sortierung hat ja nichts mit der Art der Speicherung der daten zu tun. alle alle Methoden QuckSort, BubbleSort, ShellSort, die bei Arraya funktionieren sollten auch in Listen möglich sein.
|
Re: Doppelt verkettete Liste sortieren
Hi,
also spätestens wenn du wieder indiziert auf deine Liste zugreifen kannst, dann sollten alle Algos gehen. so ganz auf die schnelle: ein dynamisches Array (mit Zeigern) aufmachen in den du Zeiger auf deine Sortier-Elemente (deine einfach verketteten Listen) ablegst, dann mit Quicksort sortieren und danach wieder deine Doppel-verkettet Liste bauen. Übrigens hängt es auch davon ab inwieweit eine Menge schon sortiert ist, welches der günstigste Algo ist. Wie stark variiert denn die "länge" deiner einfach verketteten Liste? mfg DerDan |
Re: Doppelt verkettete Liste sortieren
Zitat:
Zitat:
|
Re: Doppelt verkettete Liste sortieren
Bau Dir einen sortierten Binärbaum auf. Jetzt kannst Du Deine Elemente der doppelten Liste eins nach dem anderen in den Baum stecken und aus diesem Baum dann wieder eine doppelte Liste zusammenstellen.
Das geht so: das erste Element der Liste wird die Wurzel. das zweite wird verglichen und wenns kleiner ist, wird es das linke Kind, ansonsten das Rechte. Ist das jeweilige Kind schon besetzt, dann wird mit diesem wieder verglichen usw. Wenn der Baum fertig ist, fängst Du gaaaanz links an. Dies ist das kleinste Element und kommt als erstes in die neue Liste. Danach sein Elternknoten. Hat dieser ein rechtes Kind, gehst Du in diesem rechten Teilbaum gaaaanz nach links usw. Damit die Einfügesuche beschleunigt wird, kannst Du die Tiefe des Baumes reduzieren, indem Du nach jedem Einfügen den Baum austarierst. Dazu solltest Du aber mal nach nem Tut über Binärbäume suchen, das würde hier zu weit führen. Dieses Verfahren hätte wenigstens nur O=n*lb(n), im Gegensatz zu bubbleSort (n^2). Der ist der einzige, der mir gerade einfällt, der auch ohne Indexierung auskommt. Ach ja: und sorge dafür dass die Anzahl der Elemente jedes Elements nur einmal berechnet wird, das spart auch ganz schön Zeit. |
Re: Doppelt verkettete Liste sortieren
Ok ich habe das Ganze jetzt gelöst, indem ich einfach die Werte aus meiner Hauptliste in eine Temporäre Liste geordnet eingefügt habe.
Das ganze funktioniert einwandfrei und der Zeitaufwand geht auch noch. Der Speicheraufwand bleibt wie vorher, da ich einsortierte Werte sofort aus der Hauptliste lösche. die Doppelte Verkettung hat sich damit auch erledigt, da ich diese nur für Quicksort implementiert hatte ;) Hier mein Code:
Delphi-Quellcode:
procedure sort;
var help:ptoLe; // Hilfspointer to Listenelement tmp:TDliste; // Hilfsliste begin neu(tmp); while leer(mylist)=false do begin geordnet_einfuegen(tmp,mylist.Value); // werte in Hilfsliste packen vorne_loeschen(mylist); // aus Liste Loeschen end; mylist := tmp; // Pointer der Mainlist auf die Templiste umsetzen end;
Delphi-Quellcode:
Somit wäre das erledigt.
procedure geordnet_einfuegen(var anker:PtoLe;Value:TsetOfReal);
var help,tmp:PtoLe; begin if leer(anker) = true then // 1. Sonderfall: Liste Leer hinten_anfuegen(anker,Value) else begin help := anker; // Hilfspointer setzen if help.Value.Getanzahl >= Value.Getanzahl then // 2. Sonderfall: an erster Stelle muss eingefügt werden begin new(tmp); tmp.Value := Value; tmp.next := anker; anker := tmp; end else begin while (help.next <> nil) and (help.next.Value.Getanzahl < Value.Getanzahl) do help := help.next; // Ansonsten durchgehen und schauen wo man einfügen kann if help.next <> nil then begin new(tmp); tmp.Value := Value; tmp.next := help.next; help.next := tmp; end else hinten_anfuegen(anker,Value); // Sonderfall: letzte Stelle end; end; end; Bin aber immer noch für Verbesserungen offen. |
Re: Doppelt verkettete Liste sortieren
Delphi-Quellcode:
ändern in
while leer(mylist)=false do
Delphi-Quellcode:
while not leer(mylist) do
|
Re: Doppelt verkettete Liste sortieren
Zitat:
ist doch das selbe^^ |
Re: Doppelt verkettete Liste sortieren
Nein man vergleicht einen Booleanwert nie auf True oder False!
|
Re: Doppelt verkettete Liste sortieren
Irgendwo gab es mal einen Thread, wo sehr gut beschriebn wird, wie gefährlich das ist, so auf boolsche Ausdrücke hin zu überprüfen. Habe den aber eben nicht gefunden :-\
An sich scheint es das gleiche zu sein, aber deine Abfrage kann auch mal dicke in die Hose gehen ;) |
Re: Doppelt verkettete Liste sortieren
Zitat:
Zitat:
wenn ich hingegen
Delphi-Quellcode:
schriebe kann jeder compiler das anderst interpretieren.
while leer(mylist) do
Wer sagt mir denn das es in 10 Jahren nicht ein Compiler gibt, der diesen Ausdruck standardmäßig auf false Prüft, und nicht wie Delphi auf true? und eigentlich wollte ich meine Proggs in 10 Jahren auch noch benutzen.. daher einfach true oder false dahinter o.O aber such mal bitte den Artikel.. bin auch auf der Suche... das Interessiert mich jetzt. |
Re: Doppelt verkettete Liste sortieren
|
Re: Doppelt verkettete Liste sortieren
Zitat:
|
Re: Doppelt verkettete Liste sortieren
Falscher Thread
|
Re: Doppelt verkettete Liste sortieren
Zitat:
Die Sache ist einfach die, das Boolean intern ein Byte groß ist. Wenn dieses Byte den Wert 0 hat, bedeutet das "Aus". Jeder Wert <> 0 bedeutet "An". Das Problem ist, dass die Konstanten True und False als 0 und 1 festgelegt sind. Wenn du also "=True" schreibst, wird also nicht auf Wahrheit überprüft, sondern auf die Zahl 1. Da kann es passieren, dass eine Prüfung false ergibt, obwohl sie wahr gewesen wäre: In VB bedeutet True beispielsweise nicht 1, sondern -1. Wenn du nun den Rückgabewert aus einer VB-Dll prüfst, wird deine Schreibweise imemr False ergeben! Theoretisch könnte man zumindest "variable = false" schreiben statt "not variable", aber erstens ist letzteres kürzer und zweitens ist es konsequenter. Ein kleines Konsolenprogramm zum Beweisen:
Delphi-Quellcode:
Ich hoffe, ich habe es einigermaßen verständlich rüberbringen können (Habs manchmal nicht so mit dem Erklären^^)
var
b: boolean; s: string; // Für Readln begin b := true; writeln('Test 1: b='+inttostr(ord(b))); if b then writeln(' a) Wahr') else writeln(' a) Falsch'); if b=True then writeln(' b) Wahr') else writeln(' b) Falsch'); b := boolean(byte(-1)); writeln('Test 2: b='+inttostr(ord(b))); if b then writeln(' a) Wahr') else writeln(' a) Falsch'); if b=True then writeln(' b) Wahr') else writeln(' b) Falsch'); readln(s); // Damit sich das Prrogramm nicht sofort beendet end. //Edit: kein roter Kasten... naja schadet ja nicht //Edit²: @quendolineDD: Uppsi, sorry ._. Ich weiß wirklich nicht, wie das passiert ist^^ Hab's geändert. |
Re: Doppelt verkettete Liste sortieren
Hey du hast falsch zitiert, das habe ich nie gesagt :-\
|
Re: Doppelt verkettete Liste sortieren
Hallo, für verkettete Listen eignet sich
![]() Mergesort ist zwar ein rekursiver Algorithmus, allerdings garantiert er dir eine Rekursionstiefe von log(n). Wenn du also 1267650600228229401496703205376 Werte sortierst, hast du trotzdem nur eine Rekursionstiefe von ~100. |
Re: Doppelt verkettete Liste sortieren
Zitat:
Werde ich mir mal zu Gemüte führen. OT: endlich back @ Topic^^ |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz