Methoden Erklärungshilfe

V_Fynn03

Mitglied
Hallo ich bin dabei die Programmiersprache zu lernen und bin gerade dabei lineare Datenstrukturen zu programmieren, um genau zu sein bin ich gerade dabei ein beliebiges Element in einer Liste zu löschen. Deswegen habe ich mir auch verschiedene Quelltexte im Internet angeschaut um zu sehen wie das ganze so funktioniert. Nun bin ich auf diesen Quelltext gestoßen wobei dieser nicht erklärt wurde. Könnte mir jemand Schritt für Schritt erklären was jeweils in dieser Methode passiert? Wäre sehr hilfreich. Zwar verstehe ich die Idee dahinter im Großen und Ganzen, tue mich allerdings mit der Sprache noch etwas schwer, vielen Dank. S steht auf jeden Fall für das Element was man löschen möchte.
Java:
 public boolean delete(String s) {
        Node dummy = first;
        Node last = getLast();

        if(s.equals(first.getContent())) {
            delete();
        }

        while(!(dummy.getNext().getContent().equals(s))) {
            if (s == null) {
                return false;
            }

            Node current = first;

            if (s.equals(current.getContent())) {
                first = first.getNext();
                return true;
            }

            while (current.getNext() != null && !s.equals(current.getNext().getContent())) {
               current = current.getNext();
            }

            Node NodeS = current.getNext();
            Node next = NodeS.getNext();
            current.setNext(next);
            NodeS = null;

        }
        return true;
    }
 

mihe7

Top Contributor
Zunächst muss man mal verstehen, dass die Liste Elemente nicht direkt speichert sondern in untereinander verketteten "Containern", die gerne als Knoten bzw. Node bezeichnet werden.

So ein Knoten enthält also einerseits das eigentliche Element, andererseits einen Zeiger auf den nächsten Knoten. Daher nennt man den Spaß verkettete Liste.

Das Löschen eines Elements in so einer Liste funktioniert derart, dass der betreffende Container einfach "ausgehängt" wird und die verbleibenden Container eben wieder aneinander gehängt werden (bildlich kann man sich das wie bei einem Zug vorstellen). Dabei gilt es aber, eine Besonderheit zu berücksichtigen: eine verkettete Liste ist durch einen ersten Container vollständig definiert, denn an diesem hängen alle weiteren Container. D. h. beim Löschen des ersten Containers muss es einen neuen ersten Container geben.

Der Code ist allerdings für die Tonne.
 
X

Xyz1

Gast
Wie wäre er richtig?
In etwa so
Java:
import java.util.StringJoiner;

public class SL {
	private static class Node {
		private String content = null;
		private Node next = null;

		public Node(String c) {
			content = c;
		}

		public String getContent() {
			return content;
		}

		public void setNext(Node n) {
			next = n;
		}

		public Node getNext() {
			return next;
		}
	}

	private Node first = null;

	public Node getLast() {
		Node dummy = first;
		while (dummy != null && dummy.getNext() != null) {
			dummy = dummy.getNext();
		}
		return dummy;
	}

	public void add(String c) {
		if (first == null) {
			Node dummy = new Node(c);
			dummy.setNext(first);
			first = dummy;
		} else {
			getLast().setNext(new Node(c));
		}
	}

	public void delete() {
		if (first == null) {
			throw new IllegalArgumentException("empty SL");
		}
		first = first.getNext();
	}

	public boolean delete(String s) {
		if (first == null) {
			return false;
		}

		Node dummy = first;
		Node last = getLast(); // ?

		if (first.getContent().equals(s)) {
			delete();
			return true;
		}

		while (dummy.getNext() != null && !dummy.getNext().getContent().equals(s)) {
			dummy = dummy.getNext();
		}
		if (dummy.getNext() == null) {
			return false;
		}

		dummy.setNext(dummy.getNext().getNext());
		return true;
	}

	@Override
	public String toString() {
		StringJoiner j = new StringJoiner(", ");
		Node dummy = first;
		while (dummy != null) {
			j.add(dummy.getContent());
			dummy = dummy.getNext();
		}
		return j.toString();
	}

	public static void main(String[] args) {
		SL sl = new SL();
		System.out.println(sl);
		System.out.println(sl.delete("1"));
		System.out.println(sl);
		sl.add("1");
		System.out.println(sl);
		System.out.println(sl.delete("1"));
		System.out.println(sl);
		sl.add("2");
		System.out.println(sl);
		System.out.println(sl.delete("1"));
		System.out.println(sl);
		sl.add("3");
		System.out.println(sl);
		System.out.println(sl.delete("1"));
		System.out.println(sl);
		System.out.println(sl.delete("3"));
		System.out.println(sl);
		System.out.println(sl.delete("2"));
		System.out.println(sl);
	}
}
 
X

Xyz1

Gast
Also nochmal kurz zur Erklärung, @V_Fynn03 , ich habe Deinen Code genommen und die fehlenden Methoden und Attribute nachimplementiert. Das bedeutet, der Code (auch der Entwurf usw.) ist nicht perfekt...
 

mihe7

Top Contributor
Da der Code falsch ist, kannst Du ihn stark vereinfachen: return false;

Die Frage ist nicht, wie der Code aussieht, die Frage ist, wie Du das Problem lösen möchtet. Du präsentierst hier fremden Code, den Du nicht verstehst und willst, dass wir Dir fertigen Code schreiben. Beschreibe doch mal einen Algorithmus mit einfachen Worten, also ohne Java, dann können wir Dir helfen, diesen mittels Java zu kodieren.
 
K

kneitzel

Gast
Sorry, auf was willst Du hinaus? Was ist jetzt die Problematik? @Xyz1 hat dir eine Lösung geben. Was stört Dich an der Lösung? Oder was verstehst Du nicht? Du musst uns schon Details geben. Oder sollen wir den Code jetzt iterieren?

Ansonsten eine verkürzte Variante, die die vorgegebenen Methoden hat (Aber auch nicht das sein dürfte, was Du willst, denn hier nutze ich einfach LinkedList und muss daher nur die delete Methoden (in LinkedList remove) und die toString() Methode schreiben...
Gefällt Dir das besser? Die Main habe ich einfach von @Xyz1 übernommen....

Code:
import java.util.LinkedList;

public class SL extends LinkedList<String> {

    public void delete() {
        remove();
    }

    public boolean delete(String s) {
        return remove(s);
    }

    @Override
    public String toString() {
        return String.join(", ", this.toArray(new String[size()]));
    }

    public static void main(String[] args) {
        SL sl = new SL();
        System.out.println(sl);
        System.out.println(sl.delete("1"));
        System.out.println(sl);
        sl.add("1");
        System.out.println(sl);
        System.out.println(sl.delete("1"));
        System.out.println(sl);
        sl.add("2");
        System.out.println(sl);
        System.out.println(sl.delete("1"));
        System.out.println(sl);
        sl.add("3");
        System.out.println(sl);
        System.out.println(sl.delete("1"));
        System.out.println(sl);
        System.out.println(sl.delete("3"));
        System.out.println(sl);
        System.out.println(sl.delete("2"));
        System.out.println(sl);
    }
}
 
K

kneitzel

Gast
Da der Code falsch ist, kannst Du ihn stark vereinfachen: return false;

Die Frage ist nicht, wie der Code aussieht, die Frage ist, wie Du das Problem lösen möchtet. Du präsentierst hier fremden Code, den Du nicht verstehst und willst, dass wir Dir fertigen Code schreiben. Beschreibe doch mal einen Algorithmus mit einfachen Worten, also ohne Java, dann können wir Dir helfen, diesen mittels Java zu kodieren.
Tobias hat ja fertigen Code präsentiert. Der sieht ja recht gut aus. Das delete(String) hätte ich etwas anders geschrieben, denn ich hätte hier ein previous mitgeführt und so natürlich in der schleife eine Zuweisung mehr um dann halt hinterher kürzere Zuweisungen zu haben. Aber das ist persönliches Wohlbefinden.

/e Aber du hast die komplette Logik der LinkedList überlassen. :D

Ja, das war daher auch nicht wirklich ernst gemeint. Das war halt nur eine einfache Version des Codes unter Nutzung der Möglichkeiten von Java. (Und das String.join geht natürlich auch nur in diesem Zusammenhang. Bei einer eigenen Liste wird das schon recht viel im Hintergrund und macht natürlich nur Sinn, wenn man deutlich mehr implementiert haben will. Wenn man sich den Spass macht und das wirklich selbst schreibt, dann merkt man, was da alles dahinter steckt. Iterator ist ja etwas, das in Schule und Studium noch dran kommt aber dann ist doch meist Schluss. Aber zu einem "Produkt" LinkedList kann halt deutlich mehr gehören. Stream Unterstützung, toArray, ... Da kann man sich ja mal anschauen, was da alles die LinkedList im Java Framework implementiert und bereit stellt. Ich fand das interessant damals, denn das ist ja doch eine Sache : Selbst für sich etwas entwickeln oder eben ein "Produkt" erstellen. Da kommen dann teilweise doch ungeahnte Aufwände zusammen... Aber das nur ganz am Rande...)
 

mihe7

Top Contributor
Tobias hat ja fertigen Code präsentiert. Der sieht ja recht gut aus.
Ich meinte natürlich seinen Code, nicht den von Tobias :)

Der Punkt ist: ich habe vom TE bislang keine Eigenleistung gesehen. Nachdem Tobias eine Lösung gegeben hat, gab es keine erkennbare Verständnisfrage dazu. Aber wem erkläre ich das? Du weißt, worauf ich hinaus will ;)
 
X

Xyz1

Gast
Wie gesagt, ich hatte die Methode genommen, fehlende Klassen, Attribute, Methoden usw. ergänzt und die Zeilen in der Methode so stark wie möglich vereinfacht. Sprich etwas nicht ganz Richtiges in etwas Richtiges transformiert.
Node last = getLast(); // ?
ist als Relikt übriggeblieben...

Ehm ich will nicht sagen, besser geht es nicht, da null-Checks usw. fehlen, aber ich denke auch der TE hat einfach zunächst das Interesse an dieser Fragestellung verloren.
 

Flown

Administrator
Mitarbeiter
Eine Idee wäre die AbstractList zu überschreiben, dann hättest du eine fully-fledged JDK kompatible List:
Java:
class StringList extends AbstractList<String> {

  private Node first;
  private int size;

  @Override
  public String get(int index) {
    checkIndexRange(index, false);
    Node nth = getNth(index);
    return nth.content;
  }

  @Override
  public int size() {
    return size;
  }

  @Override
  public void add(int index, String element) {
    checkIndexRange(index, true);
    Node toAdd = new Node(element);
    if (index == 0) {
      toAdd.next = first;
      first = toAdd;
    } else {
      Node cur = getNth(index - 1);
      toAdd.next = cur.next;
      cur.next = toAdd;
    }
    size++;
  }

  @Override
  public String remove(int index) {
    checkIndexRange(index, false);
    Node toDelete;
    if (index == 0) {
      toDelete = first;
      first = first.next;
    } else {
      Node cur = getNth(index - 1);
      toDelete = cur.next;
      cur.next = cur.next.next;
    }
    size--;
    return toDelete.content;
  }

  private Node getNth(int index) {
    Node cur = first;
    for (int i = 0; i < index; i++) {
      cur = cur.next;
    }
    return cur;
  }

  private void checkIndexRange(int index, boolean inclusive) {
    if (index < 0) {
      throw new IllegalArgumentException("index must not be negative");
    }
    if (inclusive && index > size || !inclusive && index >= size) {
      throw new IndexOutOfBoundsException("index exceeded size");
    }
  }

  private class Node {
    private String content;
    private Node next;

    private Node(String c) {
      content = c;
    }
  }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Erklärungshilfe Java Basics - Anfänger-Themen 18

Ähnliche Java Themen

Neue Themen


Oben