From d2cd58e2c3d8a2bb78a558f0d1d3338142bf3972 Mon Sep 17 00:00:00 2001 From: Asecave Date: Sat, 5 Dec 2020 12:23:51 +0100 Subject: [PATCH] works --- LangLauf/Athlete.java | 5 + LangLauf/BinarySearchTree.java | 440 +++++++++++++++++---------------- LangLauf/Competition.java | 27 +- LangLauf/TestCompetition.java | 5 + 4 files changed, 254 insertions(+), 223 deletions(-) diff --git a/LangLauf/Athlete.java b/LangLauf/Athlete.java index cbb1af7..6cf1675 100644 --- a/LangLauf/Athlete.java +++ b/LangLauf/Athlete.java @@ -46,4 +46,9 @@ public class Athlete implements ComparableContent { public boolean isLess(Athlete athlete) { return getFinalTime() < athlete.getFinalTime(); } + + @Override + public String toString() { + return name; + } } \ No newline at end of file diff --git a/LangLauf/BinarySearchTree.java b/LangLauf/BinarySearchTree.java index 6e21607..e852948 100644 --- a/LangLauf/BinarySearchTree.java +++ b/LangLauf/BinarySearchTree.java @@ -29,236 +29,246 @@ */ public class BinarySearchTree> { - /* --------- Anfang der privaten inneren Klasse -------------- */ + /* --------- 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; + /** + * 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> { - 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(); - } - - } + private CT content; + private BinarySearchTree left, right; - /* ----------- Ende der privaten inneren Klasse -------------- */ + 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(); + } - private BSTNode node; + } - /** - * Der Konstruktor erzeugt einen leeren Suchbaum. - */ - public BinarySearchTree() { - this.node = null; - } + /* ----------- Ende der privaten inneren Klasse -------------- */ - /** - * 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; - } + private BSTNode node; - /** - * 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); - } - } - } + /** + * Der Konstruktor erzeugt einen leeren Suchbaum. + */ + public BinarySearchTree() { + this.node = null; + } - /** - * 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 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; + } - /** - * 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; - } - } + /** + * 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 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; - } - } + /** + * 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; + } + } - /** - * 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); - } - } - } - } + /** + * 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; + } + } - /** - * 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; - } - } - } + /** + * 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; + } + } - /* ----------- Weitere private Methoden -------------- */ + /** + * 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; + } - /** - * 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(); - } - } + 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); + } + } + } + } - private BSTNode getNodeOfLeftSuccessor() { - return node.left.node; - } + /** + * 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; + } + } + } - private BSTNode getNodeOfRightSuccessor() { - return node.right.node; - } - - public void printInOrder() { - //TODO - } + /* ----------- 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 List getInOrder() { + List inOrder = new List<>(); + getPartTree(this, inOrder); + return inOrder; + } + + private void getPartTree(BinarySearchTree tree, List inOrder) { + if (tree != null && tree.getContent() != null) { + getPartTree(tree.getLeftTree(), inOrder); + inOrder.append(tree.getContent()); + getPartTree(tree.getRightTree(), inOrder); + } + } } diff --git a/LangLauf/Competition.java b/LangLauf/Competition.java index 170e729..79fc7b7 100644 --- a/LangLauf/Competition.java +++ b/LangLauf/Competition.java @@ -1,20 +1,20 @@ 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()) { @@ -22,13 +22,24 @@ public class Competition { leaderboard.insert(runners.getContent()); runners.next(); } - - leaderboard.printInOrder(); } - + public Athlete[] top3() { Athlete[] top = new Athlete[3]; - //TODO + List inOrder = leaderboard.getInOrder(); + inOrder.toFirst(); + top[0] = inOrder.getContent(); + inOrder.next(); + if (!inOrder.hasAccess()){ + return top; + } + top[1] = inOrder.getContent(); + inOrder.next(); + if (!inOrder.hasAccess()){ + return top; + } + top[2] = inOrder.getContent(); + inOrder.next(); return top; } } diff --git a/LangLauf/TestCompetition.java b/LangLauf/TestCompetition.java index 68af26e..9c35e64 100644 --- a/LangLauf/TestCompetition.java +++ b/LangLauf/TestCompetition.java @@ -18,6 +18,11 @@ public class TestCompetition { competition.newRunner("a"); competition.simulate(); + + Athlete[] top = competition.top3(); + for (int i = 0; i < top.length; i++) { + System.out.println(top[i] + ": " + top[i].getFinalTime()); + } } }