package liste;

/**
 * Eine einfach verkettete Liste mit Verweis auf den letzten Knoten
 * 
 * @author Rainer Helfrich
 * @version Oktober 2020
 */
public class ListeMitEnde<T> extends ListeIterativ<T>
{
    /**
     * Der letzte Knoten der Liste
     */
    private Listenknoten<T> ende;
    
    /**
     * Erzeugt eine neue Liste
     */
    public ListeMitEnde()
    {
        super();
        ende = 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
        {
            ende.nachfolger = neu;
        }
        ende = 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);
            if (ende == null)
            {
                ende = anfang;
            }
        } 
        else
        {
            Listenknoten<T> k = anfang;
            while (index > 1) {
                if (k == null) {
                    return; 
                } 
                k = k.nachfolger;
                index--;
            } 
            if (k == null) {
                return; 
            }
            Listenknoten<T> neu = new Listenknoten(val, k.nachfolger);
            k.nachfolger = neu;
            if (k == ende)
            {
                ende = neu;
            }
        }
    }
    
    /**
     * Gibt zurück, ob die Liste leer ist.
     * @return true, wenn die Liste keine Elemente enthält; false sonst
     */
    public boolean istLeer()
    {
        return anfang == null && ende == null;
    }

    /**
     * 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;
            if (anfang == null)
            {
                ende = null;
            }
        } 
        else
        {
            Listenknoten tmp = anfang;
            while (index > 1 && tmp != null) 
            {
                tmp = tmp.nachfolger;
                index--;
            } 
            
            if (tmp != null && tmp.nachfolger != null) 
            {
                tmp.nachfolger = tmp.nachfolger.nachfolger;
                if (tmp.nachfolger == null)
                {
                    ende = tmp;
                }
            } 
        }
    }
}
