verkettete liste ansEndeSchieben

Rouven50

Aktives Mitglied
hey.. ich lese eine beliebige zahl an ziffern ein und danach soll eine beliebige zahl aus der liste ans ende geschoben werden

zb eingabe:
1 2 3 2 5 6 3 6

zahl 2 soll an das ende:
ausgabe:
1 3 5 6 3 6 2 2

hier mein code:
Java:
class Element {
	int wert;
	Element naechstes;

	Element(int v, Element n) {
		this.wert = v;
		this.naechstes = n;
	}
}

class Liste {
	Element erstes, letztes;

	Liste() {
		this.erstes = null;
		this.letztes = null;
	}

	void hinzufuegen(int i) { // Anhaengen am Ende
		Element elem = new Element(i, null);
		if (this.erstes == null) {
			this.erstes = elem;
			this.letztes = elem;
		} else {
			this.letztes.naechstes = elem;
			this.letztes = elem;
		}
	}
}

class Eliste extends Liste {

	Eliste() {
		super();
	}

	void ansEndeSchieben(int i) {
		Element aktuell = this.erstes;
		int counter = 0;

		// durchlauft die liste
		while (aktuell != null) {
			// guckt ob der wert anders als i ist
			if (aktuell.wert != i) {
				aktuell = aktuell.naechstes;
			} else {
				counter++;
				if (aktuell.naechstes == null || this.letztes == aktuell) {
					break;
				}
				while (aktuell != this.letztes) {
					if (aktuell.naechstes == this.letztes) {
						aktuell.wert = aktuell.naechstes.wert;
						aktuell = aktuell.naechstes;
					}else{
					aktuell.wert = aktuell.naechstes.wert;
					aktuell = aktuell.naechstes;
					}
				}
				
				aktuell = this.erstes;
			}
		}

		aktuell = this.erstes;
		while (aktuell.naechstes != this.letztes) {
			aktuell = aktuell.naechstes;
		}

		this.letztes = aktuell;
		aktuell.naechstes = null;

		for (int a = 0; a < counter; a++) {
			hinzufuegen(i);
		}
	}

	void ausgabe() { // zusaetzlich - muss nicht implementiert werden
		Element aktuell = this.erstes;
		while (aktuell != null) {
			IO.print(aktuell.wert + " ");
			aktuell = aktuell.naechstes;
		}
	}
}

public class aufgabe2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int max = IO.readInt("MaxEintraege: ");
		Eliste neu = new Eliste();
		while (max > 0) {
			int zahl = IO.readInt("Zahl eingeben: ");
			neu.hinzufuegen(zahl);
			max--;
		}
		IO.println("Unsortiert: ");
		neu.ausgabe();
		IO.println();
		IO.println("----------------------\nSortiert: ");
		int sortierZahl = IO.readInt("Zahl die an das Ende soll: ");
		neu.ansEndeSchieben(sortierZahl);
		neu.ausgabe();
	}

}

allerdings geht es nur wenn die zu verschiebene zahl nur 1 mal drin vorkommt…sonst wird die zwar ans ende geschoben aber die letzte ziffer füllt die fehlenden zahlen auf also so:

eingabe:
2 2 3 4 5

zahl 2 soll verschoben werden
ausgabe:
3 4 5 5 2 2

ich weiß nicht woran das liegt..jemand ne idee?
 
Zuletzt bearbeitet von einem Moderator:
Kannst du dein Problem etwas spezifizieren?
Also soll die Methode das erste Element von hinten/vorne mit diesem Wert nach vorne schieben oder soll es alle Elemente mit dem übergebenen Wert nach vorne schieben?
 
Zuletzt bearbeitet:
- über die Liste laufen und nach passendem Element suchen
- wenn ein Element gefunden wurde, Element aus der Liste entfernen und hinten wieder anhängen

1 Schleife + 3-5 Anweisungen, mehr braucht man dazu eigentlich nicht
 
jaa genau…nur das problem ist ich weiß nicht wo mein fehler liegt…warum er mir wenn ich mehrere ziffern verschieben will den rest mit der letzten ziffer auffüllt

also 2 2 3 4 5 zu 3 4 5 5 2 2

also warum er da noch ne 5 hinzufügt…

bei 2 2 2 3 4 5 wäre es 3 4 5 5 5 2 2 2
 
Ich glaube hinzufügen ist nicht richtig. Wenn bereites ein erstes Element existiert und Du ein neues anfügen willst, setzt Du das letzte (vorher) erste auf das neue und das letzte.naechste auch auf das neue... Da ist eine Schleife gut, die ans letzte Element geht und dann den nächsten auf das Neue setzt.

P.S.: die Methode ansEndeSchieben brauchst Du dann nicht mehr. Das soll einfach hinzufuegen machen.
 
Zuletzt bearbeitet:
das komische ist ja das er das nur macht wenn die zahl die verschoben werden soll mehrmals drin vorkommt.. wenn die zahl nur einmal drin vorkommt macht er alles perfekt… nur wenn die mehrmals drin vorkommt dann füllt er die letzten "plätze" mit der letzten ziffer auf ..wie oben im beispiel
 
kann mir keiner einen tipp geben, woran es liegt?
hab den code noch bisschen gekürzt..

Java:
class Eliste extends Liste {

	Eliste() {
		super();
	}

	void ansEndeSchieben(int i) {
		Element aktuell = this.erstes;
		int counter = 0;

		// durchlauft die liste
		while (aktuell != null) {
			// guckt ob der wert anders als i ist
			if (aktuell.wert == i) {
				counter++;
				while (aktuell != this.letztes) {
					aktuell.wert = aktuell.naechstes.wert;
					aktuell = aktuell.naechstes;
				}
				aktuell = this.erstes;
			} else {
				aktuell = aktuell.naechstes;
			}

			
		}

		// i hinten dran haengen
		aktuell = this.erstes;
		while (aktuell.naechstes != this.letztes) {
			aktuell = aktuell.naechstes;
		}

		this.letztes = aktuell;
		aktuell.naechstes = null;

		for (int a = 0; a < counter; a++) {
			hinzufuegen(i);
		}
	}
 
du hast keine Interesse an eigenständigen Denken bzw das zu üben,
wartest lieber 14 Stunden und länger bis dir das jemand anders erklärt?

solche Programme sind noch mit die einfachsten die es gibt, überschaubarer Code, sogar überschaubare Anzahl an Ausführungsschritten insgesamt,
relativ anschaulich was passieren soll usw.

mit Log-Ausgaben könntest du jeden einzelnen Befehl kontrollieren und mit deiner Planung abgleichen,
ich habe eben 3 Min. paar Ausgaben hinzugefügt,
ergibt als Log
Code:
Unsortiert: 
2 2 3 4 5 
ansEndeSchieben:
nach Entfernen eines Vorkommens:
2 3 4 5 5 
nach Entfernen eines Vorkommens:
3 4 5 5 5 
vor hinzufügen: 
3 4 5 5 
counter: 2
----------------------
Sortiert: 
3 4 5 5 2 2

schon viel mehr Informationen als einfach nur auf den Code zu starren oder?
man kann im Code natürlich letztlich alles erkennen, aber das Log macht es soviel einfacher,
es sagt mir z.B. dass du 2en gar nicht so richtig entfernst sondern nur alle Einträge weiter nach vorne schreibst,
ohne an das Ende der Liste zu denken, etwa zu verkürzen, deshalb vervielfältigt sich das letzte Element,

in Zeile 30 deines zuletzt geposteten Codes hast du allerdings entsprechendes, dort wird einmalig das letzte Element entfernt,
das ist nicht so gut, denn zum einen passiert das ohne Prüfung auch, wenn gar kein zu verschiebenes Element gefunden wurde!,
teste das mal mit anderen Zahlen wie 7, da wird deine Liste einfach kürzer,

bei zu vielen 5en, wie in deinem konkreten Problem, wird nur eine entfernt, das reicht ja auch nicht,
du könntest hier auf counter schauen, wenn 0 dann gar nichts zu entfernen, bei 1 1x, bei 2 2x usw.,
da ist ein Muster zu erkennen oder?

oder du könntest gleich in der Schleife, gleich wenn i gefunden und alle Werte verschoben werden,
das Ende entfernen, das wäre passender

----

noch besser wäre ein Entfernen wie man es bei verketteten Listen generell vorsieht:
keine Werte in andere Elemente schreiben, sondern den naechstes-Zeiger des Vorgängers auf
den Nachfolger des aktuellen zu löschenden Elementes umbiegen,

fertig, nur ein Schritt, bei tausenden Elementen in einer Liste ein riesiger Fortschritt,
und der Grund, warum es eine LinkedList überhaupt gibt, bei ArrayList kommt man nicht umher, Werte an neue Positionen zu schreiben

ein bisschen mehr ist allerdings schon noch zu tun, schauen ob es überhaupt einen Vorgänger gibt,
genau darauf achten dass erstes + letztes richtig gesetzt werden usw.,

wenn du diesen Aufwand scheust, dann kannst du vorerst bei deinem Verfahren bleiben und es wie weiter oben besprochen verbessern,
das ist aber wirklich nicht im Sinne einer verketteten Liste

----

auf die Lösungen hättest du nicht unbedingt von selber kommen müssen,
aber durch Log-Ausgaben kannst du wenigstens erkennen, in welchen Schritten zusätzliche 5en usw. kommen

---

noch ein Standard-Tipp:
immer wieder über die Konsole alles einzutippen ist doch irre, verwende zum Testen
Java:
        Eliste neu = new Eliste();
        neu.hinzufuegen(2);
        neu.hinzufuegen(2);
        neu.hinzufuegen(3);
        neu.hinzufuegen(4);
        neu.hinzufuegen(5);

        System.out.println("Unsortiert: ");
        neu.ausgabe();
        System.out.println("ansEndeSchieben:");
        neu.ansEndeSchieben(2);
        System.out.println("----------------------\nSortiert: ");
        neu.ausgabe();
 
Zuletzt bearbeitet von einem Moderator:
hier mal eine Lösung, nicht schön aber funktioniert. Vielleicht hilft es dir dinene Fehler zu erkennen.
[Java]
class Eliste extends Liste {

Eliste() {
super();
}

public void ansEndeSchieben(int index) {

int counter = 1;
Element davor = this.erstes;

if (this.erstes == null) {
System.err.println("Die Liste ist Leer");
return;
}

// sonderfall
if (index == 1) {
Element tmp = this.erstes;
this.erstes = tmp.naechstes;
this.letztes.naechstes = tmp;
this.letztes = tmp;
tmp.naechstes = null;
return;
}

for (; counter < index; counter++) {
if (davor == null) {
System.err.println("Liste zu kurz");
return;
}
davor = davor.naechstes;
}
Element tmp = davor.naechstes;
davor.naechstes = tmp.naechstes;
this.letztes.naechstes = tmp;
this.letztes = tmp;
tmp.naechstes = null;
}
}
[/Java]

und noch eine Ausgabe methode.
Java:
   public void ausgabe() {
        if (this.erstes == null)
            return;

        for (Element ele = this.erstes; ele != null; ele = ele.naechstes) {
            System.out.print(ele.wert);
        }
        System.out.println("");
    }
 
einen bestimmten Index ans Ende zu schieben ist aber schon bisschen was anderes als alle Elemente mit einem gesuchten Wert,
wobei das vielleicht der Aufgabe richtiger enspricht, falls es eine Aufgabe gibt
 
danke schonmal an euch beide.. hab es bis jetzt so gemacht… funktioniert auch alles außer wenn die ziffer die verschoben werden soll mehrmals vorkommt und auch an der letzten stelle… also 2 3 4 5 2 ist er in einer endlosschleife bei 2 2 3 4 5 macht er es mittlerweile richtig und wenn man 2 3 und dann 3 eingibt …gibt er auch 2 3 aus oder wenn man zb 7 eingibt passiert auch nichts mehr..

das ist mein code:
Java:
class Eliste extends Liste {

	Eliste() {
		super();
	}

	void ansEndeSchieben(int i) {
		Element aktuell = this.erstes;
		int counter = 0;

		// durchlauft die liste
		while (aktuell != null) {
			// guckt ob der wert gleich i ist
			if (aktuell.wert == i) {
				counter++;
				if (aktuell != this.letztes) { //ueberprueft ob es noch nicht das letzte element ist
					while (aktuell != this.letztes) {
						aktuell.wert = aktuell.naechstes.wert;
						aktuell = aktuell.naechstes;
					}
					aktuell = this.erstes; // wieder an den anfang setzen
				} else { //wenn es das letzte element ist wird aktuell weitergesetzt
					aktuell = aktuell.naechstes;
				}
			} else {
				aktuell = aktuell.naechstes;
			}

		}
		//initialisieren der anzahl fuer die einzufuegenden objekte
		int pasteAnzahl = counter;
		
		// loeschen der letzten elemente
		while (counter > 0) {
			aktuell = this.erstes;
			while (aktuell.naechstes != this.letztes) {
				aktuell = aktuell.naechstes;
			}

			this.letztes = aktuell;
			aktuell.naechstes = null;
			counter--;
		}

		// einfuegen von i
		while (pasteAnzahl > 0) {
			hinzufuegen(i);
			pasteAnzahl--;
		}
	}

	void ausgabe() { // zusaetzlich - muss nicht implementiert werden
		Element aktuell = this.erstes;
		while (aktuell != null) {
			IO.print(aktuell.wert + " ");
			aktuell = aktuell.naechstes;
		}
	}
}

achja @ slaterb …ich saß gestern den ganzen tag und abend dran und hab versucht das zu verstehen..programmier halt noch nicht solange..deswegen finde ich das bisschen unverschwämt mir mir zu unterstellen das ich nur auf eine antwort warte - zumal du auch zum java-forum-team gehörst… zumal ich ja auch keine lösung haben wollte, sondern einen tipp… naja hab die ja von euch jetzt bekommen und dafür danke...🙂
 
Zuletzt bearbeitet:
das ist nicht als Wertung zu verstehen, zumal eine Tatsache, sondern als Ansporn selber aktiv zu werden,
mit einem einfachen Befehl wie System.out.println() bzw. bei dir IO.irgendwas kannst du quasi alles selber schaffen

wobei du im Moment eine Endlosschleife hast, dass ist ein natürlicher Feind, Millionen Ausgaben pro Sekunde sind nicht schön,
Thread.sleep(100) kann es verlangsamen

---

der neue Fehler ist eigentlich klar, du machst noch dasselbe wie zuvor, also mit Auffüllen von rechts,
wenn ganz am Ende die 2 steht, womit soll sie überschrieben werden? nix da, bleibt 2, die 2 wird immer wieder gefunden,

das hatte ich (auch) nicht bedacht bei meinem Vorschlag mit dem nachträglichen counter-löschen, dies bietet sich also nicht mehr an,
dann die andere Variante, gleich in der while-Schleife Ende löschen?
 
einen bestimmten Index ans Ende zu schieben ist aber schon bisschen was anderes als alle Elemente mit einem gesuchten Wert,
wobei das vielleicht der Aufgabe richtiger enspricht, falls es eine Aufgabe gibt

hey.. ich lese eine beliebige zahl an ziffern ein und danach soll eine beliebige zahl aus der liste ans ende geschoben werden

Ok habe es falsch aufgefasst. Bzw. anders verstanden :rtfm:

Dann mach es so:
bau dir eine DEL funktion, zähl die ANZAHL der "gesucht Zahl" und del() dann alle mit der gesuchten Zahl. Danach einfach die gewünschte anzahl neuer Objekte mit Wert = "gesucht zahl" hinten anhängen!

[Java]
if(next.wert == gesuchteZahl) {
next = next.naechster;
zaehler ++;
}
//...
for(int i = 0; i< zaheler; i++ {
(Eliste)neu.add((gesuchteZahl)
}
//..

public void add(int wert) {
Element neu = new Element(wert);
this.letzter.next = neu;
letzter = neu;
}

[/code]
 
Zuletzt bearbeitet:

Zurück
Oben