Node last = first; // das erste Element könnte das letzte sein.
while (last.next != null) { // Wenn last aber noch nicht das letzte Element ist,
last = last.next; // dann könnte das nächste Element das letzte sein
}
return last;
Wenn Du einen Plan hättest, dürftest Du keine Fehlermeldung erhalten. @jono, das ist keineswegs böse gemeint, aber Du zeigst mit jedem zweiten Kommentar, dass Du gar keine Grundlagen beherrschst. Du musst da echt dran arbeiten.Doch habe ich ! [...] Aber mit value ist immer noch eine Fehlermeldung, value ist noch rot gekringelt.
return value;
?Ja, mehrere. Ich habe das auch nur als "Lösung" akzeptiert, weil erkennbar war, was Du machen wolltestHabe ich sonst noch einen Fehler gemacht?
Node last = first;
for (Node i=first; i.next!=0;i=i.next)
if(i.next=null)
Return i
Node last = first;
for (Node i=first; i.next!=0;i=i.next) {
if(i.next=null) {
Return i
}
}
Node last = first;
for (Node i=first; i.next!=null;i=i.next) {
if(i.next == null) {
return i;
}
}
return ???;
Node last;
for (last = first; last.next != null; last = last.next) {
; // nichts zu tun
}
return last;
Das ist an der Stelle nichts anderes alsJa genau.
return this.value;
Du willst aber doch nicht die value der Liste, sondern des letzten Elements zurückgeben. Was musst Du also logischerweise schreiben?Okay danke für die Antwort, die fehlenden Simikolons und Schleifen kommen daher, dass ich es schnell übers Handy eingetippt habe, aber dennoch gut zu wissen das dort noch mehr Fehler drin sind.Ja, mehrere. Ich habe das auch nur als "Lösung" akzeptiert, weil erkennbar war, was Du machen wolltest
Es geht um folgenden Code:
Java:Node last = first; for (Node i=first; i.next!=0;i=i.next) if(i.next=null) Return i
Durch die fehlenden Blöcke und Einrückungen ist das ziemlich unübersichtlich, daher schreibe ich das erstmal um:
Mal abgesehen von dem Tippfehler bzgl. "return" und dem fehlenden Semikolon am Ende der Anweisung, ist die Bedingung im if-statement eine Zuweisung und kein Vergleich. Hinzu kommt, dass ein abschließendes return (außerhalb der for-Schleife) fehlt. In der Bedingung prüfst Du auf 0, das kann nicht funktionieren, denn 0 ist ein int, während i.next ein Node ist. Du müsstest also auf null prüfen.Java:Node last = first; for (Node i=first; i.next!=0;i=i.next) { if(i.next=null) { Return i } }
Berücksichtigt man diese Punkte, erhält man:
Jetzt kommen zwei weitere Punkte hinzu:Java:Node last = first; for (Node i=first; i.next!=null;i=i.next) { if(i.next == null) { return i; } } return ???;
1. was Du schon selbst angemerkt hast: Du müsstest mit last und nicht mit i arbeiten.
2. Die Bedingung im if-Statement wird niemals true sein, da diese mit der Bedingung der while-Schleife genau gegenteilig überprüft wurde. Der Schleifenkörper wird nur ausgeführt, wenn i.next != null ist, folglich gilt im Schleifenkörper i.next==null gerade nicht.
Java:Node last; for (last = first; last.next != null; last = last.next) { ; // nichts zu tun } return last;
last.value ?
Jetzt kommen zwei weitere Punkte hinzu:
1. was Du schon selbst angemerkt hast: Du müsstest mit last und nicht mit i arbeiten.
2. Die Bedingung im if-Statement wird niemals true sein, da diese mit der Bedingung der while-Schleife genau gegenteilig überprüft wurde. Der Schleifenkörper wird nur ausgeführt, wenn i.next != null ist, folglich gilt im Schleifenkörper i.next==null gerade nicht.
for (Node last = first; ; last = last.next) {
if (last.next == null) return last;
}
public void init() {
if (first.next == null) {
first = null;
last = null;
} else {
last.init.next = null;
last = last.init;
}
length--;
}
Jetzt habe ich noch Probleme bei der append und init Methode.
Prinzipiell ist das ja schonmal korrekt, jedoch wird mir last rot unterstrichen, kann ich auch hier wiederJava:public void init() { if (first.next == null) { first = null; last = null; } else { last.init.next = null; last = last.init; } length--; }
Node last = first anwenden, was ich eigentlich für sinnvoll halte?
Node last;
public void cons(int value) {
Node newElem = new Node();
newElem.value = value;
if (this.first == null) {
this.first = newElem;
} else {
Node tmp = this.first;
while (tmp.next != null) {
tmp = tmp.next;
}
tmp.next = newElem;
}
}
JUnit version 4.12
.E
Time: 0.004
There was 1 failure:
1) test(PublicTests)
java.lang.AssertionError: expected:<5> but was:<9>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at PublicTests.test(PublicTests.java:15)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Die Funktion der last Methode sieht ja so aus :Java:for (Node last = first; ; last = last.next) { if (last.next == null) return last; }
public void cons(int n) { // Hinzufuegen eines elements
Node n1 = new Node();
if(first==null) {
first.value=n;
first.next=null;
}
if(n<first.value) { // n kleiner als erstes Element bsp 5 kleiner 9
n1=first; // speicher first in n1 (n1 =9)
first.value=n; // speicher n in first (first = 5)
first.next=n1; // first next zeigt auf n1 also 9
}
if (n>first.value) { // n ist groesser als first beispiel 7 groesser als 5
n1.value=n; // speicher n in n1
first.next= n1; // n1 soll hinter first gespeichert werden
}
}
public void cons(int n) { // Hinzufuegen eines elements
Node n1 = new Node();
n1.value = n;
if (first == null) // Liste ist null n1 wird Kopfelement
first = n1;
else {
Node i;
while (first.next != null) {
if (n1.value != n) {
if (n1.value > n) { // Wenn n1 > n ist soll n1 head werden
n1.next = first;
n1.value = n;
first = n1;
}
if (n1.value < n) { // Wenn n1<n ist soll n1 hinten eingefuegt werden
n1.value = n;
n1.next = null;
while (first.next != null) {
first = first.next;
}
first.next = n1;
}
}
first=first.next;
}
}
}
import static org.junit.Assert.*;
import org.junit.Test;
public class PublicTests {
@Test
public void test() {
SortedList sList = new SortedList();
//Teste cons
sList.cons(9);
sList.cons(5);
sList.cons(7);
assertEquals(5, sList.first.value);
assertEquals(7, sList.first.next.value);
assertEquals(9, sList.first.next.next.value);
//Teste append
SortedList sList2 = new SortedList();
sList2.cons(6);
sList2.cons(8);
sList2.cons(4);
sList.append(sList2);
assertEquals(4, sList.first.value);
assertEquals(5, sList.first.next.value);
assertEquals(6, sList.first.next.next.value);
assertEquals(7, sList.first.next.next.next.value);
assertEquals(8, sList.first.next.next.next.next.value);
assertEquals(9, sList.first.next.next.next.next.next.value);
}
}
Es geht um eine SortedList...ich hätte allerdings auch eine frage undzwar bei der Methode
Richtig.Sprich wenn die Liste leer ist fehlt dann nicht noch ein entsprechender Rückgabewert?
Wenn Du eine leere List haben solltest, gilt first == null und first.next würde zu einer NullPointerException führen.Sprich wenn ich eine leere Liste haben sollte, ist first.next bzw in dem Beispiel auch gleichzeitig last.next == null und anschließend gebe ich last aus.
Ja das ist verständlich, nur verstehe ich nicht ganz wieso bei mir die Einordnung nicht funktioniert.Code:Eine SortedList l: first next next next ----> [3] ----> [5] ----> [8] ----> nil l.init(): first next next ----> [3] ----> [5] ----> nil l.cons(4) first next next next ----> [3] ----> [4] ----> [5] ----> nil
Weil Ihr Euch das nicht richtig überlegt.nur verstehe ich nicht ganz wieso bei mir die Einordnung nicht funktioniert.
first next next next
----> [3] ----> [5] ----> [8] ----> nil
first next next next
----> [3] ----> [5] ----> [8] ----> nil
^
next.value == 5 < 7 --> also weiter
first next next next
----> [3] ----> [5] ----> [8] ----> nil
^
next.value == 8 > 7 --> richtige Stelle
first next next next
----> [3] ----> [5] ----> [8] ----> nil
^
[7]---+
next
first next next
----> [3] ----> [5] [8] ----> nil
| ^
+-->[7]---+
next next
Die Logik dahinter verstehe ich, jedoch frage ich mich wie ich möglichst einfach den passenden Index in der Liste ansprechen kann.Weil Ihr Euch das nicht richtig überlegt.
Geh mal von folgender Liste aus:
Sagen wir mal, Du möchtest die 7 einfügen. Dann kann man das Problem in zwei Teile aufteilen: 1. finde den richtigen Knoten. 2. füge den neuen Knoten ein.Code:first next next next ----> [3] ----> [5] ----> [8] ----> nil
Welches wäre der richtige Knoten? Der mit der 5.
Warum? Weil wir einen Knoten immer nur hinter einen anderen hängen können und der Wert des auf die 5 folgenden Knotens größer als der einzufügende Wert ist. Ohne Berücksichtigung von Sonderfällen wandern wir also durch die Liste, bis der Wert des Nachfolgerknotens größer als der einzufügende Wert ist.
An der Stelle können wir also das neue Element einfügen. Wir können sagen, dass der Nachfolger des neuen Element gleich dem aktuellen Nachfolger sein muss:Code:first next next next ----> [3] ----> [5] ----> [8] ----> nil ^ next.value == 5 < 7 --> also weiter first next next next ----> [3] ----> [5] ----> [8] ----> nil ^ next.value == 8 > 7 --> richtige Stelle
Außerdem muss der aktuelle Nachfolger das neue Element sein:Code:first next next next ----> [3] ----> [5] ----> [8] ----> nil ^ [7]---+ next
Sonderfälle gibt es drei:Code:first next next ----> [3] ----> [5] [8] ----> nil | ^ +-->[7]---+ next next
1. Das Element muss am Ende der Liste eingefügt werden. Hier ist die Bedingung der Schleife entsprechend zu erweitern.
2. Das Element muss am Anfang einer Liste eingefügt werden.
3. Das Element muss in eine leere Liste eingefügt werden.
Die Fälle 2 und 3 werden gleich behandelt: der Nachfolger des einzufügenden Elements wird der Knoten, auf den first zeigt und first muss hinterher auf das neue erste Element zeigen.
while (n> first.next){
first.next = first.next.next;
}
Was willst Du denn mit einem Index?Die Logik dahinter verstehe ich, jedoch frage ich mich wie ich möglichst einfach den passenden Index in der Liste ansprechen kann.
Nun ja angenommen ich habe eine Liste in der bereits 3, 4, 8, und 9 gespeichert sind und in diese soll nun die 7 gespeichert werden.Was willst Du denn mit einem Index?
Ja, und wie läuft man durch eine verkettete Liste?Dann muss ich ja die Liste durch laufen bis ich raus finde wo die 7 hingehört also zwischen die 4 und die 8.
for (Node i = first ; i != null; i = i.next){
}
while (first.next != null){
first=first.next
}
Node i = first;
while (i.next != null) {
i = i.next;
}
Über die Referenz i, die auf das jeweils aktuelle Element zeigt?nur weiß ich allerdings nicht wie ich die einzelnen Stellen der Liste ansprechen kann.
Node i = first;
while (i.next != null) {
i = i.next;
if (n < i)
n.next = i;
i.init = n;
}
current wäre doch eine Möglichkeit.Was schwebt dir für ein aussagekräftigerer Name denn vor?
Es geht bei der Schleife nur darum, i an die richtige Stelle zu positionieren. Du musst also nur die Schleifenbedingung anpassen. Aktuell stellst Du schon mal sicher, dass Du nicht über das Ende der Liste hinaus läufst. Bis zum Eintreffen welcher Situation musst Du denn i auf die nächste Stelle positionieren?Geht das so in die richtige Richtung
Node i = first;
while (i.next > n ) {
i = i.next;
if(i.next < n)
i.next = n;
}
public void cons(int value) { // Hinzufuegen eines elements
// ... hier kommt noch mehr ...
Node current = first;
while (current.next != null && current.next.value < value) {
current = current.next;
}
// an der Stelle zeigt current auf den Knoten, hinter dem
// der neue Knoten eingefügt werden muss...
}
Sorry mein Fehler ich meine natürlich n.value.1. i und i.next sind Referenzen auf Node-Objekte. Die kannst Du nicht einfach mit einem int vergleichen, das hatten wir heute schon einmal...
current.next.next = n.value;
Ja. Ggf. erstellst Du am Anfang auch schon das einzufügende Node-Objekt.Ich nehme mal an mit dem Kommentar hier kommt noch mehr spielst du auf die Möglichkeit an, dass die Liste auch leer sein kann und ich in diesem Fall das Element einfach hinzufügen kann ohne diese zu durchlaufen.
Nein. Und wieder: Node-Objekte vs int...verstehe ich es dann richtig das dann quasi so aussieht ?
Also ich meinte es nicht als bloße Zahlen sondern eherNein. Und wieder: Node-Objekte vs int...
public void cons(int n) { // Hinzufuegen eines elements
Node toInsert = new Node();
toInsert.value = n;
if (first == null || first.value >= n) {
toInsert.next = first;
first = toInsert;
return;
}
Node current = first;
while (current.next != null && current.next.value <= value) {
current = current.next;
}
toInsert.next = current.next;
current.next = toInsert;
}
Könntest du mir den letzten Schritt erläutern?Bevor das hier ausartet:
Java:public void cons(int n) { // Hinzufuegen eines elements Node toInsert = new Node(); toInsert.value = n; if (first == null || first.value >= n) { toInsert.next = first; first = toInsert; return; } Node current = first; while (current.next != null && current.next.value <= value) { current = current.next; } toInsert.next = current.next; current.next = toInsert; }
Überleg doch selbst einmal in Ruhe. Sowas solltest Du selbst erkennen können!Kannst du bitte auch mal sagen, was jetzt genau mit current.next.value gemeint ist?
Wenn es eine sortierte Liste ist, dann sollte das Element mit der 5 nie auf das Element von 4 zeigen, denn dann wäre es doch nicht sortiert.Könntest du mir den letzten Schritt erläutern?
Ein Listen Objekt besteht ja aus einem Kopf in meinem Fall dann value und einem Tail in meinem Fall dann next.
Ich verstehe es gerade so das zum Beispiel der Tail von 5 auf den Tail von 4 zeigt, und der Tail von 4 auf den Kopf von 5.
Aber wäre das dann nicht nur im Kreis und würde nicht mit mehreren Elementen funktionieren?
Ich sehe das der Code zwar so funktioniert allerdings verstehe ich es noch nicht ganz.
Bevor das hier ausartet:
Java:public void cons(int n) { // Hinzufuegen eines elements Node toInsert = new Node(); toInsert.value = n; if (first == null || first.value >= n) { toInsert.next = first; first = toInsert; return; } Node current = first; while (current.next != null && current.next.value <= value) { current = current.next; } toInsert.next = current.next; current.next = toInsert; }
public void append(SortedList l1) {
if (!l1.isNil())
if (first == null) {
first = l1.first;
} else {
Node i;
for (i = first; i.next != null; i = i.next)
;
i.next = l1.first;
}
}
JUnit version 4.12
.E
Time: 0.004
There was 1 failure:
1) test(PublicTests)
java.lang.AssertionError: expected:<4> but was:<5>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at PublicTests.test(PublicTests.java:27)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Ein Listen-Objekt besteht aus Node-Objekten. Der Kopf ist ein Node-Objekt, der in der Liste mittels "first" referenziert wird.Ein Listen Objekt besteht ja aus einem Kopf in meinem Fall dann value
Schau nach, was append lt. ADT machen soll...es wäre nett wenn mir jemand einen Denkanstoß geben könnte
Schau nach, was append lt. ADT machen soll...
//Teste append SortedList sList2 = new SortedList(); sList2.cons(6); sList2.cons(8); sList2.cons(4); sList.append(sList2); assertEquals(4, sList.first.value); assertEquals(5, sList.first.next.value); assertEquals(6, sList.first.next.next.value); assertEquals(7, sList.first.next.next.next.value); assertEquals(8, sList.first.next.next.next.next.value); assertEquals(9, sList.first.next.next.next.next.next.value);
Nachdem ich registriert hatte, mit wem ich schreibe, war mir schon klar, wo das endet: mit 300 Kommentaren und am Ende schreibt man dann sowieso die Lösung Vielleicht hilft es dem Verständnis, wenn man über den Code diskutiert.aber dann gibt @mihe7 mehr oder weniger auf
Nein, das steht im ADT nicht.Es sollen zwei SortedLists angehangen werden
Richtig, was anderes macht Deine append-Methode ja auch nicht.Das würde ja an sich bedeuten, dass meine Liste nicht Sortiert ist und die Zahlen nur angehangen wurden oder?