/*
Datei............: Aufg0717.java
Projekt..........: Einführung in die Java-Programmierung
Erstellt.........: 02.11.97, Guido Krüger
Geändert.........: --
Aufgabe..........: Musterlösung zu Aufgabe 07.17
Kommentare.......:

Die Implementierung der Methoden der Klasse LinkedList wird im
Sourcecode erklärt. Der Testcode in main erzeugt zunächst eine leere
Liste und fügt dann die Zahlen von 1 bis 5 ein. Das anschließende
Durchlaufen der Liste gibt die Zahlen in umgekehrter Reihenfolge
aus (denn sie wurden ja vorne eingefügt).
*/
public class Aufg0717
{
  public static void main(String args[])
  {
	LinkedList list = new LinkedList();
	for (int i = 1; i <= 5; ++i) {
	  list.addElement(new Integer(i));
	}
	for (int i = 0; i < list.length(); ++i) {
	  Integer element = (Integer)list.getElement(i);
	  System.out.println(element.intValue());
	}
  }
}

class LinkedListNode
{
  Object element;
  LinkedListNode next;
}

class LinkedList
{
  private LinkedListNode root;

  /**
   * Der Konstruktor initialisiert die Liste durch Zuweisung von null
   * an das Wurzelelement. Dies ist der Indikator dafür, daß die Liste
   * leer ist. 
   */
  public LinkedList()
  {
	root = null;
  }

  /**
   * Ein neues Element wird vorne in der Liste angefügt, indem es 
   * instanziert wird, sein next-Zeiger auf das alte Wurzelelement 
   * zeigt und das Wurzelelement auf das neue Element verbogen wird.
   */
  public void addElement(Object obj)
  {
	LinkedListNode node = new LinkedListNode();
	node.element = obj;
	node.next = root;
	root = node;
  }

  /**
   * Um das letzte Element entfernen zu können, muß es zunächst gefunden
   * werden. Hat die Liste nur ein Element, wird sie komplett geleert,
   * andernfalls wird die Liste von vorne durchlaufen, bis das vorletzte
   * Element gefunden wurde (node.next.next == null). Bei diesem Element
   * wird einfach der next-Zeiger auf null gesetzt, um das nachfolgende
   * (also das letzte) Element abzuhängen.
   */
  public void removeElement()
  {
	if (root != null) {
	  if (root.next == null) { //nur ein Element in der Liste
		root = null;
	  } else { //mehrere Elemente in der Liste
		LinkedListNode node = root;
		while (node.next.next != null) {
		  node = node.next;
		}
		node.next = null;
	  }	  
	}
  }

  /**
   * Um die Länge der Liste zu ermitteln, werden die Elemente durchgezählt.
   * Ist die Liste leer, wird die Schleife nicht betreten und der 
   * Rückgabewert ist 0.
   */
  public int length()
  {
	int ret = 0;
	for (LinkedListNode node = root; node != null; node = node.next) {
	  ++ret;
	}
	return ret;
  }

  /**
   * Um das Element an Position pos zurückzugeben, wird es gesucht, indem
   * die Liste von Anfang an durchlaufen wird. Wir zählen den Zähler pos
   * nach jedem Schritt um 1 zurück und haben das gesuchte Element somit
   * gefunden, wenn pos auf 0 steht (das erste Element der Liste habe
   * definitionsgemäß die Position 0).
   */
  public Object getElement(int pos)
  {
	Object ret = null;
	for (LinkedListNode node = root; node != null; node = node.next) {
	  if (pos-- == 0) {
		ret = node.element;
		break;
	  }
	}
	return ret;
  }
}


