Fachhochschule Regensburg Aufgabenblatt 7 Algorithmen und Datenstrukturen Name: ________________________ Aufgabensteller: Prof. Sauer Vorname: _____________________ Januar 2002 Rinförig geschlossene Liste Aufgabe Die Struktur einer doppelt veketteten, ringförmig geschlossenen Liste kann so dargestellt werden: head int key; Object element; Knoten next; Knoten previous Abb.: Liste mit Knoten Eine leere ringförmig geschlossene Liste ist durch „head = null;“ und „empty = true;“ bestimmt. Die Methoden insert() und remove() bestimmen die Gestalt der ringförig geschlossenen Liste. Beim Einfügen eines Listenknoten ist zu unterscheiden: - die leere Liste head Abb.: Liste nach dem Einfügen eines Knoten in die leere Liste - Liste mit Knoten head int key; Object element; Knoten next; Knoten previous Abb.: Liste mit Knoten 1. Gib für die abstrakten Datentypen (ADT) Knoten und CircularList den Java-Quellcode an. a) Quellcode für Knoten _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ b) Quellcode für CircularList mit den Methoden insert() und remove() _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ 2. Die unter 1. vorliegende Lösung sollen zur Lösung des folgenden Problems (sog. JosephusProblem) herangezogen werden: Ein Reisebüro verlost eine Weltreise unter „N“ Kunden. Dazu werden die Kunden von 1 bis N durchnummeriert, eine Bediensteter des Reisebüros hat in einem Hut N Lose untergebracht. Ein Los wird aus dem Hut gezogen, es hat die Nummer M (1 <= M <= N). Zur Auswahl des glücklichen Kunden stellt man sich dann folgendes vor: Die Kunden (identifiziert durch die Nummern 1 bis N) werden in einem Kreis angeordnet und mit Hilfe der gezogenen Losnummer aus diesem Kreis entfernt. Bei bspw. 8 Kunden und der gezogenen Losnummer 3 werden, da das Abzählen bzw. Entfernen im Uhrzeigersinn erfolgt, folgende Nummern aus dem Kreis entfernt: 3, 6, 1, 5, 2, 8, 4. Die Person 7 gewinnt die Reise. Schreibe eine Hauptprogrammroutine, die die unter a) bzw. b) definierten Funktionen aufruft und eine Lösung des „Josephus-Problems“ ausgibt. _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ _________________________________________________________________________________ Lösungen /** * File: Knoten.java * @author ? */ public class Knoten { public int key; public Object element; public Knoten next; public Knoten previous; /* Konstruktoren */ public Knoten (int key, Object element) { this.key = key; this.element = element; this.next = null; this.previous = null; } public Knoten (int key) { this.key = key; this.next = null; this.previous = null; } public Knoten (Object element) { this.element = element; this.next = null; this.previous = null; } /* Ausgabe */ public void print () { System.out.print(key + " "); } } /** * File: CircularList.java * @author ? */ public class CircularList { protected Knoten head; protected boolean empty; /* Konstruktor */ public CircularList () { head = null; empty = true; } // Methoden zur Manipulation /* fuege ein neues Element ein */ public void insert (Knoten newKnoten) { if (empty) { newKnoten.next = newKnoten; newKnoten.previous = newKnoten; head = newKnoten; empty = false; } else { newKnoten.next = head; newKnoten.previous = head.previous; head.previous.next = newKnoten; head.previous = newKnoten; head = newKnoten; } } /* entferne ein Element */ public void remove (Knoten element) { if (element != null) { element.previous.next = element.next; element.next.previous = element.previous; /* Update head */ if (element == head) head = head.next; /* Ist die Liste leer? */ if (element == head) { head = null; empty = true; } } } /* Vereinige mit einer anderen Liste */ public void merge (CircularList L) { if (L == null || L.head == null) return; if (head == null) { head = L.head; empty = false; return; } Knoten previous = head.previous; L.head.previous.next = head; head.previous = L.head.previous; previous.next = L.head; L.head.previous = previous; } // Ausgabe public void print () { Knoten x = head; x.print(); x = x.next; while (x != head) { x.print(); x = x.next; } System.out.println(); } } public class Josephus { public static void main(String args[]) { // Liste mit n Personen CircularList ring = new CircularList(); // n ist die Anzahl der Personen // m ist die Abzaehlgroesse int n = Integer.parseInt(args[0]); int m = Integer.parseInt(args[1]); int i = 0; int j = 0; Knoten neuerKnoten; for (i = 1; i <= n; i++) { // belege einen Knoten mit einem key neuerKnoten = new Knoten(i); // einfuegen ring.insert(neuerKnoten); } // Ausgabe Liste ring.print(); Knoten vorg, akt; akt = ring.head; for (i= 0; i < n - 1; i++) { for (j = 0; j < m - 1; j++) { akt = akt.next; } System.out.print("Loesche Person "); akt.print(); System.out.println(); vorg = akt.previous; akt = akt.next; vorg.next = akt; akt.previous = vorg; } System.out.print("Person "); akt.print(); System.out.println("gewinnt"); } }