/media/sda-magnetic/david/Dokumente-15/fernuni-hagen/cs-i-ii/old-cs-2-03/java-new/2020-11-27-before-version2/BinTreeParamCallBackProg.java



public class BinTreeParamCallBackProg {
    public static void main (String [] args) {
        try {
            int i;
            BinTree <Person> root = new BinTree <Person> (new Person (args[0], args[1]));
            
            for (i = 2;  i < args.length;  i += 2)
                root.insertBinTree (new Person (args[i], args[i+1]));
            root.traverseBinTree ();
            
            BinTree root2 = root.filterBinTree();
            root2.traverseBinTree ();
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println ("You have to give on argument");
        }
    }
    
    public static interface BinTreePersonFilterInterface {
        public Person filter (Object o);
    }
    
    public static class BinTreePersonFilter implements BinTreePersonFilterInterface {
        @Override 
        public Person filter (Object o) {
            Person p = (Person) o;
            if (p.compareTo ( new Person("Heinrich", "Friedrichs")) != 0)
                return p;
            return null;
        }
        BinTreePersonFilter () {
        
        }
    
    }
    
    public static class Person implements Comparable {
        String firstname;
        String lastname;
        
        public Person (String firstname, String lastname) {
            this.firstname = firstname;
            this.lastname = lastname;
        }
        
        public String toString () {
            return lastname + ", " + firstname;
        }
        
        public int compareTo (Object o) {
            Person p = (Person) o;
            return toString().compareTo (p.toString());
        }
    }
    
    static public class BinTree <P extends Comparable> {
        BinTree l;
        BinTree r;
        P v;
        
        BinTree (P v) {
            this.l = null;
            this.r = null;
            this.v = v;
        }
        
        void insertBinTree (P v) {
            if (this.v.compareTo (v) < 0) {
                if (this.l == null)
                    this.l = new BinTree (v);
                else
                    this.l.insertBinTree (v);
            }
            else {
                if (this.r == null)
                    this.r = new BinTree (v);
                else
                    this.r.insertBinTree (v);
            }
        }
        
        void traverseBinTree () {
            if (this.l != null)
                this.l.traverseBinTree();
            System.out.println (this.v.toString());
            if (this.r != null)
                this.r.traverseBinTree();
        }
        
        BinTree <P> filterBinTree () {
            BinTreePersonFilterInterface x = new BinTreePersonFilter ();
            BinTree root = new BinTree (this.v);
            
            if (x.filter (this.v) != null) {
                root = new BinTree (this.v);
                if (this.l != null)
                    root.l = this.l.filterBinTree ();
                if (this.r != null)
                    root.r = this.r.filterBinTree ();
            }
            else {
               if (this.l != null) {
                    if((root = this.l.filterBinTree ()) == null) {
                        if (this.r != null)
                            root = this.r.filterBinTree ();
                        else
                            return null;
                    }
                    else {
                        if (this.r != null)
                            root.r = this.r.filterBinTree();
                        else
                            return null;
                    }
                }
                else if (this.r != null) {
                    root = this.r.filterBinTree();
                }
                else
                    return null;
            }
            return root;
        }
    }
}