Sortieralgorithmen realisiert mit selbstreferenzierenden Datenstrukturen Einleitung Um einzelne Daten oder auch Elemente sortieren zu können, müssen wir sie vergleichen können. In einer Java-Anwendung definieren wir ein entsprechendes interface, dass Methoden zum Vergleich von Elementen bzw. Objekten bereit stellt. Deshalb muss jede Klasse, die ein Element implementiert, das sortiert werden kann, die benötigte Comparator Objekte liefern. Siehe auch Figur 1. Um die Prinzipien von Sortieralgorithmen genauer zu studieren, sollen die folgenden Algorithmen unter Nutzung von selbstreferenzierenden Datenstrukturen implementiert werden: Aufgabe 1 Sortieren durch Auswahl (selection sort) und Einfügen (insertion sort), wobei die unterliegende Datenstruktur eine einfach verkettete Liste ist. Sorgen Sie dafür das die Implementierungen eine stabile Sortierung gewährleisten! Aufgabe 2 Quicksort mit Drei-Wege-Partitionierung, eine Optimierung falls viele Duplikate Elemente vorkommen. Die unterliegende Datenstruktur sollte eine einfacheoder eine doppelt-verkettete Liste sein. Aufgabe 3 Heapsort, wobei die unterliegende Datenstruktur ein Binärbaum ist. Beispiel Anwendung: Student Objekte sortieren mit hilfe eines Comparators Wir nehmen an, dass die Attribute einer Studenten bestehen aus: Vorname, Nachname, Studentnummer, PCN, und Gruppennummer; s. Abbildung 1. (Sie dürfen auch eine Klasse eigener Bauart nehmen zum testen Ihren Sortieralgorithmen.) Student Student -firstName: String -lastname: String -studentNumber: int -pcn: int -group: int Comparator STUDENTNRCOMPARATOR compare(s1:Student,s2:Student):int 1 STUDENTNAMECOMPARATOR 1 Abbildung 1: Student Klassendiagramm Ein Comparator ist Parameter der sort Methode! Der Konstruktor der Sorter-Klasse sortiert noch nichts! Der Konstruktor speichert lediglich die Items in der internen Datenstruktur im Sorter-Objekt. Ab dann kann man sich ein Comparator auswählen womit man die Items sortieren kann. Wenn man ein anderen Comparator nimmt, kan das SorterObjekt die Items neu sortieren! 1 Aufgaben 1. Implementieren Sie die Methoden: Selectionsort, Insertionsort, Quicksort & Heapsort. 2. Nehmen Sie einen einfachen und gleichzeitig flexiblen Entwurf: ein basicsort package mit Domäne-Klassen für selectionsort und insertionsort: die zB die Klasse CNode (ein vergleichbares Objekt) und die Sortier-Klasse enthält. Sie dürfen die Knoten in die verkettete Datenstrukturen vergleichbar (comparable) machen, aber das ist kein pflicht! Andere Sortiermethoden sollen in gleicher Weise dargestellt werden, s. Abbildung 2 und 3. Auf gleicher art ist ein CTNode Objekt ein Comparable Tree Node Objekt, geeignet für Bäume. Beispiel einer Klassen-Header: public class CTNode<T> implements Comparable<CTNode<T>> Abbildung 2: Comparable Nodes (dies ist nur ein Vorschlag, Sie können ohne weiteres eine andere Implentierung nehmen) 3. Die Sortierung der Studenten (oder die Objekte eigener Wahl) soll über die Namen oder über die Studentennummer oder über die PCN durchgeführt werden können. Das Java Comparator Interface soll hier mithilfen. Die Sortierklassen müssen das Sort interface implementieren, und diesen Interface schreibt die nachfolgende Methode vor: Queue<T> sort(Comparator<T> comparator) 4. Die Konstruktoren der Sortierklassen: Selectionsort, Insertionsort, Quicksort & Heapsort haben einen Array als Parameter. Diesen Array soll nicht sortiert werden!! Das Array ist nur dafür da die Items zu liefern womit die verkettet Datenstruktur befüllt wird. Eine Queue ist das Ergebnis der Sortierung (Methode sort). Das kleinste Item kommt immer als erste aus diesen Queue heraus. 5. Benutzen Sie einen testgetriebenen Ansatz zur Implementierung des Sortierungsverfahren: Schreiben Sie dazu zuerst einen Test. Dann schreiben Sie den Programmcode und führen, bitte, anschließend den Test aus. Benutzen Sie schließlich Refaktorisierung, um den Entwicklungsprozess fortzusetzen. Prinzipiell ist eine Implementierung, ausgerüstet mit einer Reihe von JUnit-Tests ausreichend! 2 Bericht • Verfasse einen Bericht, indem die Ergebnisse präsentiert werden. Alle Realisierungen der Datenstrukturen sollen eigene Implementierungen sein: die Verwendung von Java-Collections ist nicht gestattet. Alle nicht-trivialen Implementierungen sollten im Bericht erläutert werden. • Für alle Implementierungen der sort Methode aus der Sort Schnittstelle muss eine Zeit-Komplexitätsanalyse erstellt werden! • Schreiben Sie einen kurzen Teil im Bericht, in dem Sie Ihre Tests motivieren und die Testergebnisse erklären. • Die Programmdokumentation muss ein Klassendiagramm mit Attributen und Methoden enthalten. Als Basis dafür gilt das unten angegebene Klassendiagramm. sort T:Object T:Object Queue «interface» Sort «create» sort(comp:Comparator<T>):SQueue<T> heapsort +Queue() +put(T) +get():T +empty():boolean basicsort T:Object T:Object HeapSorter InsertionSorter +HeapSorter(T[] arr) +InsertionSorter(T[] arr) T:Object SelectionSorter CTNode<T> heap +SelectionSorter(T[] arr) Comparable +compareTo(obj:CTNode<T>):int T:Object 1 quicksort CTNode T:Object +CTNode(T content, Comparator<T> comp) +compareTo(CTNode<T> o):int QuickSorter +QuickSorter(T[] arr) Abbildung 3: Klassendiagramm für die Sortiermethoden. Als Beispiel ist in der heapsort package auch die CTNode-Klasse aufgenommen. Der Code der Basisstruktur ist schon in euren Repository. 3