diff --git a/LangLauf/Athlete.java b/LangLauf/Athlete.java
new file mode 100644
index 0000000..cbb1af7
--- /dev/null
+++ b/LangLauf/Athlete.java
@@ -0,0 +1,49 @@
+
+public class Athlete implements ComparableContent {
+
+ private String name;
+ private double startTime, endTime;
+
+ public Athlete(String name) {
+ this.name = name;
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public double getStartTime(){
+ return startTime;
+ }
+
+ public double getEndTime(){
+ return endTime;
+ }
+
+ public double getFinalTime(){
+ return endTime - startTime;
+ }
+
+ public void setStartTime(double startTime) {
+ this.startTime = startTime;
+ }
+
+ public void setEndTime(double endTime) {
+ this.endTime = endTime;
+ }
+
+ @Override
+ public boolean isGreater(Athlete athlete) {
+ return getFinalTime() > athlete.getFinalTime();
+ }
+
+ @Override
+ public boolean isEqual(Athlete athlete) {
+ return getFinalTime() == athlete.getFinalTime();
+ }
+
+ @Override
+ public boolean isLess(Athlete athlete) {
+ return getFinalTime() < athlete.getFinalTime();
+ }
+}
\ No newline at end of file
diff --git a/LangLauf/BinarySearchTree.java b/LangLauf/BinarySearchTree.java
new file mode 100644
index 0000000..6e21607
--- /dev/null
+++ b/LangLauf/BinarySearchTree.java
@@ -0,0 +1,264 @@
+/**
+ *
+ * Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
+ *
+ *
+ * Generische Klasse BinarySearchTree
+ *
+ *
+ * Mithilfe der generischen Klasse BinarySearchTree koennen beliebig viele
+ * Objekte in einem Binaerbaum (binaerer Suchbaum) entsprechend einer
+ * Ordnungsrelation verwaltet werden.
+ * Ein Objekt der Klasse stellt entweder einen leeren binaeren Suchbaum dar oder
+ * verwaltet ein Inhaltsobjekt sowie einen linken und einen rechten Teilbaum,
+ * die ebenfalls Objekte der Klasse BinarySearchTree sind.
+ * Die Klasse der Objekte, die in dem Suchbaum verwaltet werden sollen, muss
+ * das generische Interface ComparableContent implementieren. Dabei muss durch
+ * Ueberschreiben der drei Vergleichsmethoden isLess, isEqual, isGreater (s.
+ * Dokumentation des Interfaces) eine eindeutige Ordnungsrelation festgelegt
+ * sein.
+ * Alle Objekte im linken Teilbaum sind kleiner als das Inhaltsobjekt des
+ * binaeren Suchbaums. Alle Objekte im rechten Teilbaum sind groesser als das
+ * Inhaltsobjekt des binaeren Suchbaums. Diese Bedingung gilt (rekursiv) auch in
+ * beiden Teilbaeumen.
+ * Hinweis: In dieser Version wird die Klasse BinaryTree nicht benutzt.
+ *
+ *
+ * @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
+ * @version Generisch_03 2017-11-28
+ */
+public class BinarySearchTree> {
+
+ /* --------- Anfang der privaten inneren Klasse -------------- */
+
+ /**
+ * Durch diese innere Klasse kann man dafuer sorgen, dass ein leerer Baum
+ * null ist, ein nicht-leerer Baum jedoch immer eine nicht-null-Wurzel sowie
+ * nicht-null-Teilbaeume hat.
+ */
+ private class BSTNode> {
+
+ private CT content;
+ private BinarySearchTree left, right;
+
+ public BSTNode(CT pContent) {
+ // Der Knoten hat einen linken und rechten Teilbaum, die
+ // beide von null verschieden sind. Also hat ein Blatt immer zwei
+ // leere Teilbaeume unter sich.
+ this.content = pContent;
+ left = new BinarySearchTree();
+ right = new BinarySearchTree();
+ }
+
+ }
+
+ /* ----------- Ende der privaten inneren Klasse -------------- */
+
+ private BSTNode node;
+
+ /**
+ * Der Konstruktor erzeugt einen leeren Suchbaum.
+ */
+ public BinarySearchTree() {
+ this.node = null;
+ }
+
+ /**
+ * Diese Anfrage liefert den Wahrheitswert true, wenn der Suchbaum leer ist,
+ * sonst liefert sie den Wert false.
+ *
+ * @return true, wenn der binaere Suchbaum leer ist, sonst false
+ *
+ */
+ public boolean isEmpty() {
+ return this.node == null;
+ }
+
+ /**
+ * Falls der Parameter null ist, geschieht nichts.
+ * Falls ein bezueglich der verwendeten Vergleichsmethode isEqual mit
+ * pContent uebereinstimmendes Objekt im geordneten binaeren Suchbau
+ * enthalten ist, passiert nichts.
+ * Achtung: hier wird davon ausgegangen, dass isEqual genau dann true
+ * liefert, wenn isLess und isGreater false liefern.
+ * Andernfalls (isLess oder isGreater) wird das Objekt pContent entsprechend
+ * der vorgegebenen Ordnungsrelation in den BinarySearchTree eingeordnet.
+ *
+ * @param pContent
+ * einzufuegendes Objekt vom Typ ContentType
+ *
+ */
+ public void insert(ContentType pContent) {
+ if (pContent != null) {
+ if (isEmpty()) {
+ this.node = new BSTNode(pContent);
+ } else if (pContent.isLess(this.node.content)) {
+ this.node.left.insert(pContent);
+ } else if(pContent.isGreater(this.node.content)) {
+ this.node.right.insert(pContent);
+ }
+ }
+ }
+
+ /**
+ * Diese Anfrage liefert den linken Teilbaum des binaeren Suchbaumes.
+ * Wenn er leer ist, wird null zurueckgegeben.
+ *
+ * @return den linken Teilbaum (Objekt vom Typ BinarySearchTree)
+ * bzw. null, wenn der Suchbaum leer ist
+ *
+ */
+ public BinarySearchTree getLeftTree() {
+ if (this.isEmpty()) {
+ return null;
+ } else {
+ return this.node.left;
+ }
+ }
+
+ /**
+ * Diese Anfrage liefert das Inhaltsobjekt des Suchbaumes. Wenn der Suchbaum
+ * leer ist, wird null zurueckgegeben.
+ *
+ * @return das Inhaltsobjekt vom Typ ContentType bzw. null, wenn der aktuelle
+ * Suchbaum leer ist
+ *
+ */
+ public ContentType getContent() {
+ if (this.isEmpty()) {
+ return null;
+ } else {
+ return this.node.content;
+ }
+ }
+
+ /**
+ * Diese Anfrage liefert den rechten Teilbaum des binaeren Suchbaumes.
+ * Wenn er leer ist, wird null zurueckgegeben.
+ *
+ * @return den rechten Teilbaum (Objekt vom Typ BinarySearchTree)
+ * bzw. null, wenn der aktuelle Suchbaum leer ist
+ *
+ */
+ public BinarySearchTree getRightTree() {
+ if (this.isEmpty()) {
+ return null;
+ } else {
+ return this.node.right;
+ }
+ }
+
+ /**
+ * Falls ein bezueglich der verwendeten Vergleichsmethode mit
+ * pContent uebereinstimmendes Objekt im binaeren Suchbaum enthalten
+ * ist, wird dieses entfernt. Falls der Parameter null ist, aendert sich
+ * nichts.
+ *
+ * @param pContent
+ * zu entfernendes Objekt vom Typ ContentType
+ *
+ */
+ public void remove(ContentType pContent) {
+ if (isEmpty() || pContent == null ) {
+ // Abbrechen, da kein Element zum entfernen vorhanden ist.
+ return;
+ }
+
+ if (pContent.isLess(node.content)) {
+ // Element ist im linken Teilbaum zu loeschen.
+ node.left.remove(pContent);
+ } else if (pContent.isGreater(node.content)) {
+ // Element ist im rechten Teilbaum zu loeschen.
+ node.right.remove(pContent);
+ } else {
+ // Element ist gefunden.
+ if (node.left.isEmpty()) {
+ if (node.right.isEmpty()) {
+ // Es gibt keinen Nachfolger.
+ node = null;
+ } else {
+ // Es gibt nur rechts einen Nachfolger.
+ node = getNodeOfRightSuccessor();
+ }
+ } else if (node.right.isEmpty()) {
+ // Es gibt nur links einen Nachfolger.
+ node = getNodeOfLeftSuccessor();
+ } else {
+ // Es gibt links und rechts einen Nachfolger.
+ if (getNodeOfRightSuccessor().left.isEmpty()) {
+ // Der rechte Nachfolger hat keinen linken Nachfolger.
+ node.content = getNodeOfRightSuccessor().content;
+ node.right = getNodeOfRightSuccessor().right;
+ } else {
+ BinarySearchTree previous = node.right
+ .ancestorOfSmallRight();
+ BinarySearchTree smallest = previous.node.left;
+ this.node.content = smallest.node.content;
+ previous.remove(smallest.node.content);
+ }
+ }
+ }
+ }
+
+ /**
+ * Falls ein bezueglich der verwendeten Vergleichsmethode isEqual mit
+ * pContent uebereinstimmendes Objekt im binaeren Suchbaum enthalten ist,
+ * liefert die Anfrage dieses, ansonsten wird null zurueckgegeben.
+ * Falls der Parameter null ist, wird null zurueckgegeben.
+ *
+ * @param pContent
+ * zu suchendes Objekt vom Typ ContentType
+ * @return das gefundene Objekt vom Typ ContentType, bei erfolgloser Suche null
+ *
+ */
+ public ContentType search(ContentType pContent) {
+ if (this.isEmpty() || pContent == null) {
+ // Abbrechen, da es kein Element zu suchen gibt.
+ return null;
+ } else {
+ ContentType content = this.getContent();
+ if (pContent.isLess(content)) {
+ // Element wird im linken Teilbaum gesucht.
+ return this.getLeftTree().search(pContent);
+ } else if (pContent.isGreater(content)) {
+ // Element wird im rechten Teilbaum gesucht.
+ return this.getRightTree().search(pContent);
+ } else if (pContent.isEqual(content)) {
+ // Element wurde gefunden.
+ return content;
+ } else {
+ // Dieser Fall sollte nicht auftreten.
+ return null;
+ }
+ }
+ }
+
+ /* ----------- Weitere private Methoden -------------- */
+
+ /**
+ * Die Methode liefert denjenigen Baum, dessen linker Nachfolger keinen linken
+ * Nachfolger mehr hat. Es ist also spaeter moeglich, in einem Baum im
+ * rechten Nachfolger den Vorgaenger des linkesten Nachfolgers zu finden.
+ *
+ */
+ private BinarySearchTree ancestorOfSmallRight() {
+ if (getNodeOfLeftSuccessor().left.isEmpty()) {
+ return this;
+ } else {
+ return node.left.ancestorOfSmallRight();
+ }
+ }
+
+ private BSTNode getNodeOfLeftSuccessor() {
+ return node.left.node;
+ }
+
+ private BSTNode getNodeOfRightSuccessor() {
+ return node.right.node;
+ }
+
+ public void printInOrder() {
+ //TODO
+ }
+
+}
diff --git a/LangLauf/ComparableContent.java b/LangLauf/ComparableContent.java
new file mode 100644
index 0000000..c07baa1
--- /dev/null
+++ b/LangLauf/ComparableContent.java
@@ -0,0 +1,60 @@
+ /**
+ *
+ * Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
+ *
+ *
+ * Generisches Interface (Schnittstelle) ComparableContent
+ *
+ *
+ *
Das generische Interface ComparableContent legt die Methoden
+ * fest, ueber die Objekte verfuegen muessen, die in einen binaeren Suchbaum
+ * (BinarySearchTree) eingefuegt werden sollen. Die Ordnungsrelation wird in
+ * Klassen, die ComparableContent implementieren durch Ueberschreiben der drei
+ * implizit abstrakten Methoden isGreater, isEqual und isLess festgelegt.
+ *
+ *
+ * @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
+ * @version Generisch_02 2014-03-01
+ */
+public interface ComparableContent {
+
+ /**
+ * Wenn festgestellt wird, dass das Objekt, von dem die Methode aufgerufen
+ * wird, bzgl. der gewuenschten Ordnungsrelation groesser als das Objekt
+ * pContent ist, wird true geliefert. Sonst wird false geliefert.
+ *
+ * @param pContent
+ * das mit dem aufrufenden Objekt zu vergleichende Objekt vom
+ * Typ ContentType
+ * @return true, wenn das aufrufende Objekt groesser ist als das Objekt
+ * pContent, sonst false
+ */
+ public boolean isGreater(ContentType pContent);
+
+ /**
+ * Wenn festgestellt wird, dass das Objekt, von dem die Methode aufgerufen
+ * wird, bzgl. der gewuenschten Ordnungsrelation gleich gross wie das Objekt
+ * pContent ist, wird true geliefert. Sonst wird false geliefert.
+ *
+ * @param pContent
+ * das mit dem aufrufenden Objekt zu vergleichende Objekt vom
+ * Typ ContentType
+ * @return true, wenn das aufrufende Objekt gleich gross ist wie das Objekt
+ * pContent, sonst false
+ */
+ public boolean isEqual(ContentType pContent);
+
+ /**
+ * Wenn festgestellt wird, dass das Objekt, von dem die Methode aufgerufen
+ * wird, bzgl. der gewuenschten Ordnungsrelation kleiner als das Objekt
+ * pContent ist, wird true geliefert. Sonst wird false geliefert.
+ *
+ * @param pContent
+ * das mit dem aufrufenden Objekt zu vergleichende Objekt vom
+ * Typ ContentType
+ * @return true, wenn das aufrufende Objekt kleiner ist als das Objekt
+ * pContent, sonst false
+ */
+ public boolean isLess(ContentType pContent);
+
+}
diff --git a/LangLauf/Competition.java b/LangLauf/Competition.java
new file mode 100644
index 0000000..170e729
--- /dev/null
+++ b/LangLauf/Competition.java
@@ -0,0 +1,34 @@
+
+public class Competition {
+
+ private List runners;
+ private BinarySearchTree leaderboard;
+ private RaceSimulator sim;
+
+ public Competition() {
+ runners = new List<>();
+ leaderboard = new BinarySearchTree<>();
+ sim = new RaceSimulator();
+ }
+
+ public void newRunner(String name) {
+ runners.append(new Athlete(name));
+ }
+
+ public void simulate() {
+ runners.toFirst();
+ while (runners.hasAccess()) {
+ sim.simulate(runners.getContent());
+ leaderboard.insert(runners.getContent());
+ runners.next();
+ }
+
+ leaderboard.printInOrder();
+ }
+
+ public Athlete[] top3() {
+ Athlete[] top = new Athlete[3];
+ //TODO
+ return top;
+ }
+}
diff --git a/LangLauf/List.java b/LangLauf/List.java
new file mode 100644
index 0000000..8c82b92
--- /dev/null
+++ b/LangLauf/List.java
@@ -0,0 +1,345 @@
+ /**
+ *
+ * Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
+ *
+ *
+ * Generische Klasse List
+ *
+ *
+ * Objekt der generischen Klasse List verwalten beliebig viele linear
+ * angeordnete Objekte vom Typ ContentType. Auf hoechstens ein Listenobjekt,
+ * aktuellesObjekt genannt, kann jeweils zugegriffen werden.
+ * Wenn eine Liste leer ist, vollstaendig durchlaufen wurde oder das aktuelle
+ * Objekt am Ende der Liste geloescht wurde, gibt es kein aktuelles Objekt.
+ * Das erste oder das letzte Objekt einer Liste koennen durch einen Auftrag zum
+ * aktuellen Objekt gemacht werden. Ausserdem kann das dem aktuellen Objekt
+ * folgende Listenobjekt zum neuen aktuellen Objekt werden.
+ * Das aktuelle Objekt kann gelesen, veraendert oder geloescht werden. Ausserdem
+ * kann vor dem aktuellen Objekt ein Listenobjekt eingefuegt werden.
+ *
+ *
+ * @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
+ * @version Generisch_06 2015-10-25
+ */
+public class List {
+
+ /* --------- Anfang der privaten inneren Klasse -------------- */
+
+ private class ListNode {
+
+ private ContentType contentObject;
+ private ListNode next;
+
+ /**
+ * Ein neues Objekt wird erschaffen. Der Verweis ist leer.
+ *
+ * @param pContent das Inhaltsobjekt vom Typ ContentType
+ */
+ private ListNode(ContentType pContent) {
+ contentObject = pContent;
+ next = null;
+ }
+
+ /**
+ * Der Inhalt des Knotens wird zurueckgeliefert.
+ *
+ * @return das Inhaltsobjekt des Knotens
+ */
+ public ContentType getContentObject() {
+ return contentObject;
+ }
+
+ /**
+ * Der Inhalt dieses Kontens wird gesetzt.
+ *
+ * @param pContent das Inhaltsobjekt vom Typ ContentType
+ */
+ public void setContentObject(ContentType pContent) {
+ contentObject = pContent;
+ }
+
+ /**
+ * Der Nachfolgeknoten wird zurueckgeliefert.
+ *
+ * @return das Objekt, auf das der aktuelle Verweis zeigt
+ */
+ public ListNode getNextNode() {
+ return this.next;
+ }
+
+ /**
+ * Der Verweis wird auf das Objekt, das als Parameter uebergeben
+ * wird, gesetzt.
+ *
+ * @param pNext der Nachfolger des Knotens
+ */
+ public void setNextNode(ListNode pNext) {
+ this.next = pNext;
+ }
+
+ }
+
+ /* ----------- Ende der privaten inneren Klasse -------------- */
+
+ // erstes Element der Liste
+ ListNode first;
+
+ // letztes Element der Liste
+ ListNode last;
+
+ // aktuelles Element der Liste
+ ListNode current;
+
+ /**
+ * Eine leere Liste wird erzeugt.
+ */
+ public List() {
+ first = null;
+ last = null;
+ current = null;
+ }
+
+ /**
+ * Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthaelt,
+ * sonst liefert sie den Wert false.
+ *
+ * @return true, wenn die Liste leer ist, sonst false
+ */
+ public boolean isEmpty() {
+ // Die Liste ist leer, wenn es kein erstes Element gibt.
+ return first == null;
+ }
+
+ /**
+ * Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt,
+ * sonst liefert sie den Wert false.
+ *
+ * @return true, falls Zugriff moeglich, sonst false
+ */
+ public boolean hasAccess() {
+ // Es gibt keinen Zugriff, wenn current auf kein Element verweist.
+ return current != null;
+ }
+
+ /**
+ * Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses
+ * nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in
+ * der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach
+ * Ausfuehrung des Auftrags kein aktuelles Objekt, d.h. hasAccess() liefert
+ * den Wert false.
+ */
+ public void next() {
+ if (this.hasAccess()) {
+ current = current.getNextNode();
+ }
+ }
+
+ /**
+ * Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles
+ * Objekt. Ist die Liste leer, geschieht nichts.
+ */
+ public void toFirst() {
+ if (!isEmpty()) {
+ current = first;
+ }
+ }
+
+ /**
+ * Falls die Liste nicht leer ist, wird das letzte Objekt der Liste
+ * aktuelles Objekt. Ist die Liste leer, geschieht nichts.
+ */
+ public void toLast() {
+ if (!isEmpty()) {
+ current = last;
+ }
+ }
+
+ /**
+ * Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das
+ * aktuelle Objekt zurueckgegeben, andernfalls (hasAccess() == false) gibt
+ * die Anfrage den Wert null zurueck.
+ *
+ * @return das aktuelle Objekt (vom Typ ContentType) oder null, wenn es
+ * kein aktuelles Objekt gibt
+ */
+ public ContentType getContent() {
+ if (this.hasAccess()) {
+ return current.getContentObject();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent
+ * ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst
+ * geschieht nichts.
+ *
+ * @param pContent
+ * das zu schreibende Objekt vom Typ ContentType
+ */
+ public void setContent(ContentType pContent) {
+ // Nichts tun, wenn es keinen Inhalt oder kein aktuelles Element gibt.
+ if (pContent != null && this.hasAccess()) {
+ current.setContentObject(pContent);
+ }
+ }
+
+ /**
+ * Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues
+ * Objekt vor dem aktuellen Objekt in die Liste eingefuegt. Das aktuelle
+ * Objekt bleibt unveraendert.
+ * Wenn die Liste leer ist, wird pContent in die Liste eingefuegt und es
+ * gibt weiterhin kein aktuelles Objekt (hasAccess() == false).
+ * Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste
+ * nicht leer ist oder pContent gleich null ist, geschieht nichts.
+ *
+ * @param pContent
+ * das einzufuegende Objekt vom Typ ContentType
+ */
+ public void insert(ContentType pContent) {
+ if (pContent != null) { // Nichts tun, wenn es keinen Inhalt gibt.
+ if (this.hasAccess()) { // Fall: Es gibt ein aktuelles Element.
+
+ // Neuen Knoten erstellen.
+ ListNode newNode = new ListNode(pContent);
+
+ if (current != first) { // Fall: Nicht an erster Stelle einfuegen.
+ ListNode previous = this.getPrevious(current);
+ newNode.setNextNode(previous.getNextNode());
+ previous.setNextNode(newNode);
+ } else { // Fall: An erster Stelle einfuegen.
+ newNode.setNextNode(first);
+ first = newNode;
+ }
+
+ } else { //Fall: Es gibt kein aktuelles Element.
+
+ if (this.isEmpty()) { // Fall: In leere Liste einfuegen.
+
+ // Neuen Knoten erstellen.
+ ListNode newNode = new ListNode(pContent);
+
+ first = newNode;
+ last = newNode;
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Falls pContent gleich null ist, geschieht nichts.
+ * Ansonsten wird ein neues Objekt pContent am Ende der Liste eingefuegt.
+ * Das aktuelle Objekt bleibt unveraendert.
+ * Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefuegt
+ * und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false).
+ *
+ * @param pContent
+ * das anzuhaengende Objekt vom Typ ContentType
+ */
+ public void append(ContentType pContent) {
+ if (pContent != null) { // Nichts tun, wenn es keine Inhalt gibt.
+
+ if (this.isEmpty()) { // Fall: An leere Liste anfuegen.
+ this.insert(pContent);
+ } else { // Fall: An nicht-leere Liste anfuegen.
+
+ // Neuen Knoten erstellen.
+ ListNode newNode = new ListNode(pContent);
+
+ last.setNextNode(newNode);
+ last = newNode; // Letzten Knoten aktualisieren.
+ }
+
+ }
+ }
+
+ /**
+ * Falls es sich bei der Liste und pList um dasselbe Objekt handelt,
+ * pList null oder eine leere Liste ist, geschieht nichts.
+ * Ansonsten wird die Liste pList an die aktuelle Liste angehaengt.
+ * Anschliessend wird pList eine leere Liste. Das aktuelle Objekt bleibt
+ * unveraendert. Insbesondere bleibt hasAccess identisch.
+ *
+ * @param pList
+ * die am Ende anzuhaengende Liste vom Typ List
+ */
+ public void concat(List pList) {
+ if (pList != this && pList != null && !pList.isEmpty()) { // Nichts tun,
+ // wenn pList und this identisch, pList leer oder nicht existent.
+
+ if (this.isEmpty()) { // Fall: An leere Liste anfuegen.
+ this.first = pList.first;
+ this.last = pList.last;
+ } else { // Fall: An nicht-leere Liste anfuegen.
+ this.last.setNextNode(pList.first);
+ this.last = pList.last;
+ }
+
+ // Liste pList loeschen.
+ pList.first = null;
+ pList.last = null;
+ pList.current = null;
+ }
+ }
+
+ /**
+ * Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess()
+ * == false), geschieht nichts.
+ * Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das
+ * aktuelle Objekt geloescht und das Objekt hinter dem geloeschten Objekt
+ * wird zum aktuellen Objekt.
+ * Wird das Objekt, das am Ende der Liste steht, geloescht, gibt es kein
+ * aktuelles Objekt mehr.
+ */
+ public void remove() {
+ // Nichts tun, wenn es kein aktuelle Element gibt oder die Liste leer ist.
+ if (this.hasAccess() && !this.isEmpty()) {
+
+ if (current == first) {
+ first = first.getNextNode();
+ } else {
+ ListNode previous = this.getPrevious(current);
+ if (current == last) {
+ last = previous;
+ }
+ previous.setNextNode(current.getNextNode());
+ }
+
+ ListNode temp = current.getNextNode();
+ current.setContentObject(null);
+ current.setNextNode(null);
+ current = temp;
+
+ //Beim loeschen des letzten Elements last auf null setzen.
+ if (this.isEmpty()) {
+ last = null;
+ }
+ }
+ }
+
+ /**
+ * Liefert den Vorgaengerknoten des Knotens pNode. Ist die Liste leer, pNode
+ * == null, pNode nicht in der Liste oder pNode der erste Knoten der Liste,
+ * wird null zurueckgegeben.
+ *
+ * @param pNode
+ * der Knoten, dessen Vorgaenger zurueckgegeben werden soll
+ * @return der Vorgaenger des Knotens pNode oder null, falls die Liste leer ist,
+ * pNode == null ist, pNode nicht in der Liste ist oder pNode der erste Knoten
+ * der Liste ist
+ */
+ private ListNode getPrevious(ListNode pNode) {
+ if (pNode != null && pNode != first && !this.isEmpty()) {
+ ListNode temp = first;
+ while (temp != null && temp.getNextNode() != pNode) {
+ temp = temp.getNextNode();
+ }
+ return temp;
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/LangLauf/README.TXT b/LangLauf/README.TXT
new file mode 100644
index 0000000..0ad193f
--- /dev/null
+++ b/LangLauf/README.TXT
@@ -0,0 +1,14 @@
+------------------------------------------------------------------------
+Dies ist die README-Datei des Projekts. Hier sollten Sie Ihr Projekt
+beschreiben.
+Erzählen Sie dem Leser (jemand, der nichts über dieses Projekt weiss),
+alles, was er/sie wissen muss. Üblicherweise sollte der Kommentar
+zumindest die folgenden Angaben umfassen:
+------------------------------------------------------------------------
+
+PROJEKTBEZEICHNUNG:
+PROJEKTZWECK:
+VERSION oder DATUM:
+WIE IST DAS PROJEKT ZU STARTEN:
+AUTOR(EN):
+BENUTZERHINWEISE:
diff --git a/LangLauf/RaceSimulator.java b/LangLauf/RaceSimulator.java
new file mode 100644
index 0000000..aebb00d
--- /dev/null
+++ b/LangLauf/RaceSimulator.java
@@ -0,0 +1,16 @@
+
+import java.util.Random;
+
+public class RaceSimulator {
+
+ private Random random;
+
+ public RaceSimulator() {
+ random = new Random();
+ }
+
+ public void simulate(Athlete athlete) {
+ athlete.setStartTime(0);
+ athlete.setEndTime(random.nextDouble());
+ }
+}
diff --git a/LangLauf/TestCompetition.java b/LangLauf/TestCompetition.java
new file mode 100644
index 0000000..68af26e
--- /dev/null
+++ b/LangLauf/TestCompetition.java
@@ -0,0 +1,23 @@
+
+
+
+public class TestCompetition {
+
+ Competition competition;
+
+ public TestCompetition() {
+ competition = new Competition();
+
+ competition.newRunner("a");
+ competition.newRunner("b");
+ competition.newRunner("c");
+ competition.newRunner("d");
+ competition.newRunner("e");
+ competition.newRunner("f");
+ competition.newRunner("g");
+ competition.newRunner("a");
+
+ competition.simulate();
+ }
+
+}
diff --git a/LangLauf/package.bluej b/LangLauf/package.bluej
new file mode 100644
index 0000000..010c1c9
--- /dev/null
+++ b/LangLauf/package.bluej
@@ -0,0 +1,95 @@
+#BlueJ package file
+dependency1.from=RaceSimulator
+dependency1.to=Athlete
+dependency1.type=UsesDependency
+dependency2.from=TestCompetition
+dependency2.to=Competition
+dependency2.type=UsesDependency
+dependency3.from=Competition
+dependency3.to=List
+dependency3.type=UsesDependency
+dependency4.from=Competition
+dependency4.to=Athlete
+dependency4.type=UsesDependency
+dependency5.from=Competition
+dependency5.to=BinarySearchTree
+dependency5.type=UsesDependency
+dependency6.from=Competition
+dependency6.to=RaceSimulator
+dependency6.type=UsesDependency
+dependency7.from=BinarySearchTree
+dependency7.to=ComparableContent
+dependency7.type=UsesDependency
+editor.fx.0.height=1000
+editor.fx.0.width=1296
+editor.fx.0.x=-8
+editor.fx.0.y=-8
+objectbench.height=93
+objectbench.width=1256
+package.divider.horizontal=0.6
+package.divider.vertical=0.8890122086570478
+package.editor.height=794
+package.editor.width=1145
+package.editor.x=0
+package.editor.y=0
+package.frame.height=1000
+package.frame.width=1296
+package.numDependencies=7
+package.numTargets=7
+package.showExtends=true
+package.showUses=true
+project.charset=UTF-8
+readme.height=58
+readme.name=@README
+readme.width=47
+readme.x=10
+readme.y=10
+target1.height=50
+target1.name=Competition
+target1.showInterface=false
+target1.type=ClassTarget
+target1.width=100
+target1.x=560
+target1.y=390
+target2.height=50
+target2.name=TestCompetition
+target2.showInterface=false
+target2.type=ClassTarget
+target2.width=130
+target2.x=780
+target2.y=280
+target3.height=50
+target3.name=RaceSimulator
+target3.showInterface=false
+target3.type=ClassTarget
+target3.width=110
+target3.x=370
+target3.y=470
+target4.height=50
+target4.name=List
+target4.showInterface=false
+target4.type=ClassTarget
+target4.width=150
+target4.x=430
+target4.y=240
+target5.height=50
+target5.name=ComparableContent
+target5.showInterface=false
+target5.type=InterfaceTarget
+target5.width=250
+target5.x=100
+target5.y=70
+target6.height=50
+target6.name=Athlete
+target6.showInterface=false
+target6.type=ClassTarget
+target6.width=80
+target6.x=180
+target6.y=320
+target7.height=50
+target7.name=BinarySearchTree
+target7.showInterface=false
+target7.type=ClassTarget
+target7.width=230
+target7.x=350
+target7.y=170