![]() |
Insertion Sort Problem
Hallo zusammen,
ich habe eine verkettete Liste die ich per InsertionSort sortieren soll. Mein Listenelement sieht so aus:
Delphi-Quellcode:
Wie soll ich denn nun aber Listenelemente vertauschen?! Ich verstehe nicht wie ich dann den Elementen ihr neues "next" zuweisen soll und das es dann sortiert wird...eiegntlich verstehe ich überhaupt nicht wie ich einen InsertionSort auf so etwas anwenden soll :(
type
tNatZahl = 0..maxint; tRefListe = ^tListe; tListe = record info : tNatZahl; next : tRefListe; end; var RefListe : tRefListe; Habt ihr da einen Tip für mich? Gruß Dragi |
Re: Insertion Sort Problem
Hi,
Insertion-Sort sagt im einfachsten Fall nichts darüber aus, dass du nur eine feste Menge von Elementen verwendest. Wenn du nicht diese explizite Einschränkung hast (dass du in-place sortieren musst), dann kannst du einfach mit zwei Listen arbeiten. Verwende einfach eine zweite sortierte Liste. Die ist am Anfang leer, dann machst du genau das, was der Insertion-Sort vorsieht, du nimmst das kleinste (größte) Element der unsortierten Liste und fügst es nun als letztes Element der bereits sortierten Liste ein. Getauscht wird eigentlich eher bei anderen Sortierverfahren. Zum tauschen müsstest du vorallem auch den Vorgänger kennen. Wie man an den rankommt ist dabei eine Frage der Implementierung. An sich ist es aber beim Insertion-Sort nie nötig! Gruß Der Unwissende |
Re: Insertion Sort Problem
Für was out-of-place sortieren? InsertionSort is doch geradezu gemacht dafür Verkettete Listen zu sortieren... Warum? Verschieben is bei verketteten Listen O(1), bei arrays O(n)(naja nciht ganz, das wär jetzt worst-case. Im average-case isses etwas besser). Du kannst also annähernd linear sortieren! Jedenfalls in Bezug auch die Zuweisungen[1].
Alles was du dazu brauchst is ne Move-Prozedur/Methode. Die sieht ungefähr so aus:
Delphi-Quellcode:
[1] Die Vergleiche sind da wider etwas schlechter, als bei den arrays, da der Zugriff aufwändiger ist. Da aber InsertionSort sowieso relativ wenige Vergleiche braucht, is InsertionSort in diesem Fall sehr gut geeignet...
// Pseudocode:
// Element entfernen: VorherigesElement.Next := Element.Next; // Element an der gegebenen Stelle einfügen: Element.Next := ElementVorRichtigerPosition.Next; ElementVorRichtigerPosition.Next := Element; mfg Christian |
Re: Insertion Sort Problem
Zitat:
Nur wie gesagt, erstmal ist es vielleicht leichter, nur den Insertion-Sort mit zwei Listen zu verstehen, da ist schon das Einfügen in der sortierten Liste und das Löschen aus der unsortierten drin. |
Re: Insertion Sort Problem
Zitat:
Zitat:
- Root-Pointer(der is eigentlich sowieso da) - Pointer auf das gerade betrachtete Element - Pointer, der auf den Anfang des unsortierten Bereiches(bzw. auf das nächste zu sortierende Element) zeigt[1] - Pointer, der den sortierten Bereich durchläuft. Zitat:
[1] Könnte man zwar weglassen, aber dann hat man wider zig vergleiche mehr zu machen... mfg Christian |
Re: Insertion Sort Problem
Zitat:
In-place wäre es wohl auch dann, wenn man eine zweite Liste nimmt, denn hier wird nur konstant viel mehr an Speicher gebraucht (jedes Element ist immer nur in einer der beiden Listen, egal ob real existent oder nicht). In einer verketteten Liste werden doch eh nur die Zeiger auf ein Element gespeichert, also brauch ich hier nie ein Element neu erzeugen, ich verschiebe nur den Speicher. Wenn man sich nun die verkettete Liste als eine lineare Struktur, die hintereinander im Speicher liegt vorstellt (kann man machen, denn man folgt eh nur den Zeigern, was dazwischen im Speicher liegt interessiert uns für die Liste schließlich nicht), dann könnte man sich die Liste als eine Art Array dyn. Länge vorstellen (eine gewisse Vereinfachung, rein virtueller Natur!). Hier finde ich kann man sich leichter vorstellen mit zwei Listen zu arbeiten, als zwei Zeiger auf der gleichen Liste zu verwenden (ist nur meine Meinung). Der Overhead einer zweiten Liste bestünde nun darin, dass man diese zwischen-speichern müsste. Man braucht also einen Zeiger auf das erste Element der Liste (und aus Bequemlichkeit einen auf das letzte Element, ermöglicht schnelles anhängen, ist aber nicht nötig). Das sind also zwei Zeiger, die man benötigt. Kling finde ich nach einem vertretbaren und vorallem konstanten Overhead. Da hier eh nur mit Zeigern gearbeitet wird, kann ich Elemente einfach verschieben, ohne dass ich die je kopieren muss. Also brauche ich nur konstant viel mehr Speicher (ca. 8 Byte). Das wäre also (entgegen meiner ersten Behauptung) durchaus in-place, gebe ich dir Recht! Jetzt finde ich es aber immer noch leichter, dass ich mir vorstelle, dass ich eine sortierte Liste und eine unsortierte habe. Am Anfang ist dann die sortierte Liste leer, die unsortierte voll. Jetzt durchsucht man alle Elemente der unsortierten Liste und nimmt das kleinste raus. Dies wird nun in die sortierte Liste getan. So macht man weiter. Die Frage ist also, wie nimmt man ein Element aus einer Liste heraus und wie fügt man es in eine Liste ein. Da hat r2c2 ja schon einiges zu gesagt. Wie man das letztlich realisiert ist jedoch auf mehr als eine Art und Weise möglich (wie vielleicht aus den letzten Beiträgen inkl. diesem hervor geht). Falls der Threadsteller hier nicht auf eine einfach verkettete Liste eingeschränkt ist, so bietet sich eine doppelt verkettete Liste an, diese kennt dann auch ihren Vorgänger, dass macht das ausgliedern eines Elements leichter. |
Re: Insertion Sort Problem
Zitat:
|
Re: Insertion Sort Problem
Zitat:
Egal, die sind an sich aber auch nicht soweit voneinander entfernt. Leichter macht es die Sache aber irgendwie schon. Gruß Der Unwissende |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:49 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 by Thomas Breitkreuz