Feld von verketteten Listen

Estor

Mitglied
Hallo, ich bin ein ziemlicher Anfänger was Java betrifft und daher ist die Lösung meines Problems hoffentlich nicht allzu schwer, vermutlich stehe ich nur irgendwo auf dem Schlauch.
Ich will ein Feld anlegen in welchem verkettete Listen abgespeichert sind (ohne die Bibliothek für Listen zu benutzen).
Mein Code sieht ungefähr so aus:
Java:
public class FeldVonVerkettetenListen {
       
    Listenelement[] liste;
    int feldanzahl;

    public FeldVonVerkettetenListen(int feldanzahl) {
        this.feldanzahl = feldanzahl;
        liste = new Listenelement[feldanzahl];
        for (int i=0; i < feldanzahl; i++) {
            liste[i] = new Listenelement(0);  //Liegt hier der Fehler?
        }
    }

    class Listenelement {
        
        int wert;
        Listenelement next;
        
        public int getWert() {
            return wert;
        }

        public Listenelement(int wert) {
            this.wert = wert;
        }

        public Listenelement getNext() {
            return next;
        }

        public void setNext(Listenelement next) {
            this.next = next;
        }
        
    }

}
<liste.length; i++)="" {
<liste.length; i++)="" {
<liste.length; i++)="" {
<liste.length;i++) {
<liste.length;i++) {<liste.length;="" i++)="" {

Die Klasse Übergabe wird aufgerufen, das Feld vom Typ Listenelemente mit "felderanzahl" Feldern angelegt und dann dachte ich, dass ich die jeweiligen Felder mit "new Listenelement(0)" belegen kann, so dass als Wert die 0 abgespeichert ist und ich auch darauf zugreifen kann. Versuche ich allerdings den Wert eines Feldes abzurufen (mit "liste[feldanzahl-1].getWert()" kommt eine Nullpointerexeption.
Muss ich erst noch eine seperate Klasse für die verkettete Liste erstellen?
Läuft irgendetwas mit den Methoden schief?
Wie gesagt, ich habe nicht besonders viel Erfahrung und würde mich über Tipps freuen 🙂</liste.length;i++)></liste.length;i++)></liste.length;></liste.length;></liste.length;>
 
Zuletzt bearbeitet:
Es wäre mal gut zu wissen,wie der Code genau aussieht.

Weil der Code den du gepostet hast, macht wenig Sinn.
Erstmal hab ich so eine for-Schleife noch nie gesehen:
Java:
  for (int i=0; i<liste.length; i++)=""
Wofür das ="". Sollte ein Syntax Error sein.

Und zweitens gibts den Konstruktor "Übergabe", ohne dass es die Klasse irgendwo gibt.
Von daher wäre es ganz gut, den kompletten Code mal zu sehen.

Grüße
 
So ich hoffe ich habs ausgebessert :/ Das mit dem Konstruktor war natürlich blöd, ich hab soviel rumprobiert, dass ich viel weggelassen habe, der Übersicht wegen. Dabei sind wohl einige Fehler passiert. Wie siehts nun aus?
Also ich sollte vielleicht mal genauer beschreiben, worum es geht: Es geht um eine Aufgabe in der eine Adjazenzliste für einen Graphen erstellt werden muss. D.h. von der main aus wird die knotenanzahl/feldanzahl eingegeben um die Adjazenzliste zu erstellen und dann werden bestimmte Konstruktoren der Klasse Graph/FeldVonVerkettetenListen aufgerufen (hinzufügen, löschen und suchen), um Kanten aus der Adjazenzliste eben hinzuzufügen, zu suchen, oder zu löschen.
Mein Problem ist nun die Umsetzung der Adjazenzliste, da ich eine Nullpointerexeption kriege, wenn ich auf den Wert eines Elements zugreifen will "liste[knoten].getWert".
Soll ich die Main und die restlichen Methoden der Klasse "FeldVonVerkettetenListen" hier nochmal posten der Übersicht halber, oder kann man schon erkennen was das Problem ist?
 
Dann hier mal die komplette Aufgabe (wobei die Frage nur ist, was ich falsch mache bei der Feldbelegung mit Listenelementen, aber vielleicht hilft es ja dabei zu verstehen, was ich will):

Nochmal als Überblick, es geht darum eine Adjazenzliste zu erstellen die für eine eingegebene Knotenanzahl Kanten hinzufügen, löschen und suchen kann und Ergebnisse zurückliefert, die abgetestet werden.
Ich habe die Kommentare vom Prof jetzt mal dringelassen.

Die main zu Testzwecken (unveränderbar):
Java:
public class Testtreiber{
    public static void main (String[] args) {
    IGraph g = new Graph_MeinName(5);
    boolean status;
    if (g.kanteErfragen(3,4)==0)
        System.out.println("Erfolgreich: Kante (3,4) ist nicht vorhanden");
    else
        System.out.println("Fehler: Kante (3,4) wird fehlerhaft gemeldet");
    status = g.kanteHinzufuegen(2, 5);
    if (status) 
        System.out.println("Erfolgreich: Kante (2,5) hinzugefuegt");
    else
        System.out.println("Fehler: Kante (2,5) nicht hinzugefuegt");
    status = g.kanteHinzufuegen(2, 3);
    if (status) 
        System.out.println("Erfolgreich: Kante (2,3) hinzugefuegt");
    else
        System.out.println("Fehler: Kante (2,3) nicht hinzugefuegt");
    if (g.kanteErfragen(2,3)==2)
        System.out.println("Erfolgreich: Kante (2,3) mit zwei Vgl.");
    else
        System.out.println("Fehler bei Suche nach Kante (2,3) ");
    
    }
}

Das Interface (unveränderbar):
Java:
public interface IGraph {

    /* Ein Graph besteht aus Knoten der Menge 1,...,n und
       ist als Adjazenzliste gespeichert. Neue Kanten werden
       am Ende der betroffenen verketteten Liste angefuegt.
       Die Variable n wird individuell beim Anlegen eines
       Objekts bestimmt. Die Kanten koennen zur Laufzeit 
       modifiziert werden.
    */

    /* Kante wird eingefuegt.
       Eingaben: Knotennummern des Start- bzw. Zielknotens
       Ausgabe: true, falls erfolgreich Kante neu gesetzt; sonst: false
    */
    public boolean kanteHinzufuegen(int von, int nach);

    /* Es wird geprueft, ob die Kante vorhanden ist.
       Eingaben: Knotennummern des Start- bzw. Zielknotens
       Ausgabe: 0, falls die Kante nicht existiert; sonst: die Anzahl der 
       Vergleiche (bzw. betrachteten Kanten), um die Kante zu finden.
     */
    public int kanteErfragen(int von, int nach);

    /* Die Kante wird entfernt.
       Eingaben: Knotennummern des Start- bzw. Zielknotens
       Ausgabe: keine
     */
    public void kanteLoeschen(int von, int nach);

}

Die Klasse in der programmiert wird:
Java:
public class Graph_MeinName implements IGraph {

    /* In den Attributen muss die Adjazenzliste verankert werden */


    /* Der Konstruktor hat ein Argument: die Anzahl der Knoten n 
     */
    public Graph_MeinName(int knotenzahl) {

    }

    /* Kante wird eingefuegt.
       Eingaben: Knotennummern des Start- bzw. Zielknotens
       Ausgabe: true, falls erfolgreich Kante neu gesetzt; sonst: false
    */
    public boolean kanteHinzufuegen(int von, int nach) {
    return false;
    }

    /* Es wird geprueft, ob die Kante vorhanden ist.
       Eingaben: Knotennummern des Start- bzw. Zielknotens
       Ausgabe: 0, falls die Kante nicht existiert; sonst: die Anzahl der 
       Vergleiche (bzw. betrachteten Kanten), um die Kante zu finden.
     */
    public int kanteErfragen(int von, int nach) {
    return -1;
    }

    /* Die Kante wird entfernt.
       Eingaben: Knotennummern des Start- bzw. Zielknotens
       Ausgabe: keine
     */
    public void kanteLoeschen(int von, int nach) {

    }

}

Meine Idee war, wie ich hoffe oben zu sehen ist, eine Klasse für die Elemente der verketteten Liste zu erstellen (diese hat also einen Wert (Knoten auf den die Kante zeigt) und einen Verweis auf den Nachfolger (next)).
Dann wird ein Feld von diesen Listenelementen erstellt (also die Adjazenzliste im Sinne von: "liste[knotenvon]" mit dem Wert "knotennach" und das next führt zum nächsten Element welches den Wert eines anderen Knoten hat mit dem "knotenvon" verbunden ist). Später wollte ich dann "kanteLoeschen" etc. schreiben für die ich auch schon konkrete Vorstellungen habe. Soweit der Plan...
Haken tut es im Moment an der Implementierung der Adjazenzliste, da ich anscheinend entweder bei meiner Listenelement-Klasse einen Fehler habe, bei der Belegung des Feldes mit Listenelementen oder irgendwo sonst. Ich vermute mal es ist etwas wirklich blödes, da ich bis jetzt nicht besonders viel mit Java gemacht habe.
Vielen Dank für jede Antwort 😉
 
FeldVonVerkettenListen ist soweit korrekt und sollte keine Probleme bereiten.
Zeig daher mal deinen Code, bei dem das Problem auftritt. Also wo machst du liste[feldanzahl-1].getWert() ?
 
Java:
    public boolean kanteHinzufuegen(int von, int nach) {
        //falsche Knotennummer und bereits vorhandensein beachten
        if (!(von < 1 || knotenzahl < von || nach < 1 || knotenzahl < nach)) {
            Listenelement pos = liste[von-1];
            while (pos != null && pos.getWert() != nach) {
                pos = pos.getNext();
            }
            if (pos.getWert() == nach) { //Hier tritt die Nullpointerexception auf, auch wenn ich "pos" mit "liste[von-1].getWert" ersetze.
                return false;
            }
            //Das anhaengen hab ich auch in der class Listenelement, aber daran liegts ja nicht
            else {
                liste[von-1].anhaengen(nach);
                return true;
            }
        }
        else {
            return false;
        }
    }<von ||="" nach<1="" knotenzahl<nach))="" {

Alles noch nicht ganz ausgereift, da ich eben über die NPE(???) gestolpert bin und nicht weiterwusste :/

</von>
 
Zuletzt bearbeitet:
ich würde mal raten das hier dein Problem liegt:
Java:
 Listenelement pos = liste[von-1];
  while (pos != null && pos.getWert() != nach) {
                pos = pos.getNext();
            }
Nach der ersten Zeile ist pos ungleich null.
In der nächsten Zeile wird nun geprüft, ob pos!=null ist (das ist es auch) und ob pos.getWert()!=nach ist (das ist vermutlich auch der Fall) => pos wird auf pos.getNext() gesetzt, aber pos.getNext liefert null => pos ist null => NPE
 
Oh man... Danke... Mensch ist mir das peinlich 😳
Das mir das nicht aufgefallen ist... Na ja vielen, vielen Dank nochmal und ich versuch mich jetzt weiter am Programm!
 
Zwei Fragen: Erstens, wenn ich pos mit liste belege, wird dann auch liste auf liste.next gesetzt, wenn ich pos = pos.getNext() schreibe?
Zweitens: Jetzt hab ich den Code folgendermaßen umgeändert:
Java:
while (pos.getNext() != null && pos.getWert() != nach) { //NPE
                pos = pos.getNext();
            }
Jetzt bekomme ich schon bei der while-Schleife eine NPE, aber eigentlich müsste doch alles okay sein, oder? Schließlich müsste jedes Element, welches auf ein weiteres Element ungleich NULL verweist auch einen Wert haben, den man abfragen kann...
 
Ah okay hat sich erledigt, es klappt doch 🙂 Nochmal vielen Dank, ich weiß jetzt dank dir woran es lag und es hat nur nicht geklappt weil ich zwischendurch noch was umgestellt hatte 😉
 

Zurück
Oben