simulator done
This commit is contained in:
49
LangLauf/Athlete.java
Normal file
49
LangLauf/Athlete.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
public class Athlete implements ComparableContent<Athlete> {
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
264
LangLauf/BinarySearchTree.java
Normal file
264
LangLauf/BinarySearchTree.java
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Generische Klasse BinarySearchTree<ContentType>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Mithilfe der generischen Klasse BinarySearchTree koennen beliebig viele
|
||||||
|
* Objekte in einem Binaerbaum (binaerer Suchbaum) entsprechend einer
|
||||||
|
* Ordnungsrelation verwaltet werden. <br />
|
||||||
|
* 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.<br />
|
||||||
|
* 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. <br />
|
||||||
|
* 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. <br />
|
||||||
|
* Hinweis: In dieser Version wird die Klasse BinaryTree nicht benutzt.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||||
|
* @version Generisch_03 2017-11-28
|
||||||
|
*/
|
||||||
|
public class BinarySearchTree<ContentType extends ComparableContent<ContentType>> {
|
||||||
|
|
||||||
|
/* --------- 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<CT extends ComparableContent<CT>> {
|
||||||
|
|
||||||
|
private CT content;
|
||||||
|
private BinarySearchTree<CT> 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<CT>();
|
||||||
|
right = new BinarySearchTree<CT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------- Ende der privaten inneren Klasse -------------- */
|
||||||
|
|
||||||
|
private BSTNode<ContentType> 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.<br />
|
||||||
|
* Falls ein bezueglich der verwendeten Vergleichsmethode isEqual mit
|
||||||
|
* pContent uebereinstimmendes Objekt im geordneten binaeren Suchbau
|
||||||
|
* enthalten ist, passiert nichts. <br />
|
||||||
|
* Achtung: hier wird davon ausgegangen, dass isEqual genau dann true
|
||||||
|
* liefert, wenn isLess und isGreater false liefern. <br />
|
||||||
|
* 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<ContentType>(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. <br />
|
||||||
|
* Wenn er leer ist, wird null zurueckgegeben.
|
||||||
|
*
|
||||||
|
* @return den linken Teilbaum (Objekt vom Typ BinarySearchTree<ContentType>)
|
||||||
|
* bzw. null, wenn der Suchbaum leer ist
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public BinarySearchTree<ContentType> 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. <br />
|
||||||
|
* Wenn er leer ist, wird null zurueckgegeben.
|
||||||
|
*
|
||||||
|
* @return den rechten Teilbaum (Objekt vom Typ BinarySearchTree<ContentType>)
|
||||||
|
* bzw. null, wenn der aktuelle Suchbaum leer ist
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public BinarySearchTree<ContentType> 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<ContentType> previous = node.right
|
||||||
|
.ancestorOfSmallRight();
|
||||||
|
BinarySearchTree<ContentType> 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. <br />
|
||||||
|
* 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<ContentType> ancestorOfSmallRight() {
|
||||||
|
if (getNodeOfLeftSuccessor().left.isEmpty()) {
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
return node.left.ancestorOfSmallRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BSTNode<ContentType> getNodeOfLeftSuccessor() {
|
||||||
|
return node.left.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BSTNode<ContentType> getNodeOfRightSuccessor() {
|
||||||
|
return node.right.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printInOrder() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
60
LangLauf/ComparableContent.java
Normal file
60
LangLauf/ComparableContent.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Generisches Interface (Schnittstelle) ComparableContent<ContentType>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <p>Das generische Interface ComparableContent<ContentType> 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.
|
||||||
|
* </p>
|
||||||
|
* </p>
|
||||||
|
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||||
|
* @version Generisch_02 2014-03-01
|
||||||
|
*/
|
||||||
|
public interface ComparableContent<ContentType> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
||||||
34
LangLauf/Competition.java
Normal file
34
LangLauf/Competition.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
public class Competition {
|
||||||
|
|
||||||
|
private List<Athlete> runners;
|
||||||
|
private BinarySearchTree<Athlete> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
345
LangLauf/List.java
Normal file
345
LangLauf/List.java
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Generische Klasse List<ContentType>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Objekt der generischen Klasse List verwalten beliebig viele linear
|
||||||
|
* angeordnete Objekte vom Typ ContentType. Auf hoechstens ein Listenobjekt,
|
||||||
|
* aktuellesObjekt genannt, kann jeweils zugegriffen werden.<br />
|
||||||
|
* Wenn eine Liste leer ist, vollstaendig durchlaufen wurde oder das aktuelle
|
||||||
|
* Objekt am Ende der Liste geloescht wurde, gibt es kein aktuelles Objekt.<br />
|
||||||
|
* 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. <br />
|
||||||
|
* Das aktuelle Objekt kann gelesen, veraendert oder geloescht werden. Ausserdem
|
||||||
|
* kann vor dem aktuellen Objekt ein Listenobjekt eingefuegt werden.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||||
|
* @version Generisch_06 2015-10-25
|
||||||
|
*/
|
||||||
|
public class List<ContentType> {
|
||||||
|
|
||||||
|
/* --------- 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. <br />
|
||||||
|
* Wenn die Liste leer ist, wird pContent in die Liste eingefuegt und es
|
||||||
|
* gibt weiterhin kein aktuelles Objekt (hasAccess() == false). <br />
|
||||||
|
* 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.<br />
|
||||||
|
* Ansonsten wird ein neues Objekt pContent am Ende der Liste eingefuegt.
|
||||||
|
* Das aktuelle Objekt bleibt unveraendert. <br />
|
||||||
|
* 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.<br />
|
||||||
|
* 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<ContentType>
|
||||||
|
*/
|
||||||
|
public void concat(List<ContentType> 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.<br />
|
||||||
|
* Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das
|
||||||
|
* aktuelle Objekt geloescht und das Objekt hinter dem geloeschten Objekt
|
||||||
|
* wird zum aktuellen Objekt. <br />
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
14
LangLauf/README.TXT
Normal file
14
LangLauf/README.TXT
Normal file
@@ -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:
|
||||||
16
LangLauf/RaceSimulator.java
Normal file
16
LangLauf/RaceSimulator.java
Normal file
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
23
LangLauf/TestCompetition.java
Normal file
23
LangLauf/TestCompetition.java
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
95
LangLauf/package.bluej
Normal file
95
LangLauf/package.bluej
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user