package liste;

/**
 * Eine einfach verkettete Liste
 * 
 * @author Rainer Helfrich
 * @version Oktober 2020
 */
public class ListeIterativ<T> extends ListeMitVerkettung<T>
{
    /**
     * Erzeugt eine neue Liste
     */
    public ListeIterativ()
    {
        anfang = null;  
    }

    /**
     * Gibt die Anzahl der Elemente der Liste zurück
     */
    public int laenge()
    {
        int len = 0;
        Listenknoten<T> k = anfang;
        while (k != null) { 
            k = k.nachfolger;
            len++;
        } 
        return len;
    }

    /**
     * Gibt den n-ten Wert (0-basierte Zählweise) der Liste zurück.
     * @param n Der Index des gewünschten Elements
     * @return Den n-ten Wert
     */
    public T getNtenWert(int n)
    {
        Listenknoten<T> k = anfang;
        while (k != null) { 
            if (n == 0) {
                return k.daten;
            } 
            k = k.nachfolger;
            n--;
        } 
        return null; 
    }

    /**
     * Hängt einen neuen Wert hinten an die Liste an.
     * @param val Der anzuhängende Wert
     */
    public void anhaengen(T val)
    {
        Listenknoten<T> neu = new Listenknoten(val, null);
        if (anfang == null) 
        {
            anfang = neu;
        } 
        else
        {
            Listenknoten<T> k = anfang;
            while (k.nachfolger != null) { 
                k = k.nachfolger;
            } 
            k.nachfolger = neu;
        }
    }

    /**
     * Fügt einen neuen Wert an einer gewünschten Stelle in der Liste ein.
     * @param index Die Stelle, an der der neue Wert stehen soll (0 <= index <= laenge())
     * @param val Der einzufügende Wert
     */
    public void einfuegenBei(int index, T val)
    {
        if (index == 0) 
        {
            anfang = new Listenknoten(val, anfang);
        } 
        else
        {
            Listenknoten<T> k = anfang;
            while (index > 1) {
                if (k == null) {
                    return; 
                } 
                k = k.nachfolger;
                index--;
            } 
            if (k == null) {
                return; 
            }
            k.nachfolger = new Listenknoten(val, k.nachfolger);
        }
    }

    /**
     * Gibt die Listenelemente hintereinander auf der Konsole aus.
     */
    public void ausgeben()
    {
        Listenknoten<T> k = anfang;
        while (k != null) { 
            System.out.print(k.daten + " ");
            k = k.nachfolger;
        } 
        System.out.println();
    }

    /**
     * Gibt zurück, ob ein Wert sich in der Liste befindet
     * @param val Der zu suchende Wert
     * @return true, wenn der Wert enthalten ist; false sonst
     */
    public boolean enthaelt(T val)
    {
        Listenknoten<T> k = anfang;
        while (k != null) { 
            if (k.daten.equals(val)) {
                return true;
            } 
            k = k.nachfolger;
        } 
        return false;
    }

    /**
     * Entfernt das Element, das am gegebenen Index steht, aus der Liste.
     * @param index Die Stelle, von der der Wert entfernt werden soll.
     */
    public void entferneBei(int index)
    {
        if (anfang == null) {
            return;
        } 
        if (index == 0) {
            anfang = anfang.nachfolger;
        } 
        else
        {
            Listenknoten tmp = anfang;
            while (index > 1 && tmp != null) {
                tmp = tmp.nachfolger;
                index--;
            } 
            if (tmp != null && tmp.nachfolger != null) {
                tmp.nachfolger = tmp.nachfolger.nachfolger;
            } 
        }
    }
}