public class Set<T>
{
    /**
     * erster Eintrag der Liste
     */
    public Node<T> first;
    
    /**
     * Konstruktor
     */
    public Set() {}
    
    /**
     * Überprüft, ob die Liste leer ist
     * 
     * @return true, wenn keine Elemente in der Liste
     */
    public boolean isEmpty() {
        return first == null;
    }
    
    /**
     * Berechnet die Größe der Liste
     * 
     * @return Anzahl der Elemente in der Liste
     */
    public int size() {
        Node<T> current = first;
        int laenge = 0;
        
        while (current != null) {
            current = current.next;
            laenge++;
        }
        
        return laenge;
    }

    /**
     * Überprüft, ob die Liste einen konkreten Wert enthält
     */
    public boolean contains(T wert) {
        Node<T> current = first;
        
        while (current != null) {
            if (current.wert == wert) return true;
            
            current = current.next;
        }
        
        return false;
    }

    /**
     * Fügt ein neues Element am Anfang der Liste ein
     */
    public void add(T neu) {
        if (contains(neu)) return;
        
        Node n = new Node<T>(neu); // Neue Node mit Zahl "neu" anlegen
        
        n.next = first;
        first = n;
    }
        
    /**
     * Löscht das Element mit dem angegebenen Wert
     */
    public void remove(T wert) {
        if (!contains(wert)) return;
        
        if (first.wert == wert) {
            first = first.next;
        } else {
            Node<T> current = first;

            if (current.next.wert == wert) {
                current.next = current.next.next;
                return;
            }
        }
    }
    
    /**
     * Bildet die Schnittmenge
     */
    public Set<T> intersection(Set<T> s) {
        Set<T> neu = new Set<T>();
        
        Node<T> current = first;
        
        // gehe alle Elemente in this durch
        while (current != null) {
            // wenn auch s das Element enthält...
            if (s.contains(current.wert)) {
                // ... füge es der Schnittmenge hinzu
                neu.add(current.wert);
            }
            current = current.next;
        }
        
        return neu;
    }
    
    /**
     * Bildet die Vereinigungsmenge
     */
    public Set<T> union(Set<T> s) {
        Set<T> neu = new Set<T>();
        
        // gehe aktuelles Set durch und füge alle Werte zum
        // neuen hinzu
        Node<T> current = first;
        while (current != null) {
            neu.add(current.wert);
            current = current.next;
        }
        
        // gehe s durch und füge alle Werte hinzu
        // doppelte Einträge werden bei add automatisch
        // gefiltert und nicht doppelt eingetragen
        Node<T> current2 = s.first;
        while (current2 != null) {
            neu.add(current2.wert);
            current2 = current2.next;
        }
        
        return neu;
    }
    
    /**
     * Bildet die Differenz
     */
    public Set<T> difference(Set<T> s) {
        Set<T> neu = new Set<T>();
        
        // gehe aktuelles Set durch
        Node<T> current = first;
        while (current != null) {
            // falls der Wert nicht in s enthalten ist...
            if (!s.contains(current.wert)) {
                // ... füge den zur Differenz hinzu
                neu.add(current.wert);
            }
        }
        
        return neu;
    } 
    
    /**
     * Überprüft, ob s eine Teilmenge ist
     */
    public boolean subset(Set<T> s) {
        Node<T> current = s.first;
        // gehe alle Elemente in s durch
        while(current != null) {
            // falls ein Wert nicht in this ist...
            if (!contains(current.wert)) {
                // ... ist s keine Teilmenge und kann abgebrochen werden
                return false;
            }
        }
        // läuft die Schleife bis zum Ende, dann sind alle
        // Elemente aus s auch in this enthalten, dann ist
        // s also eine Teilmenge von this
        return true;
    }
}