homedukeAlgorithmen & Datenstrukturen mit Java: Listen als einfach verkettete Listen Prof. Dr. Uwe Schmidt FH Wedel

Listen als einfach verkettete Listen

weiter

weiter

LinkedList mit Generics

List
implementiert als einfach verkettete Liste
persistente Implementierung
destruktive Variante in Kommentaren
Generics
weiter
   1package ds.persistent.genlist;
   2
   3/** Implementation of single linked lists with generics.
   4
   5    This implementation is a PERSISTENT one.
   6*/
   7
   8import java.util.Iterator;
   9
  10import static ds.util.Undef.undefined;
  11
  12public abstract class LinkedList<E>
  13    implements Iterable<E> {
  14
  15    //----------------------------------------
  16    // the smart constructors
  17
  18    // empty list
  19    @SuppressWarnings("unchecked")
  20    public static <E> LinkedList<E> empty() {
  21        return
  22            (LinkedList<E>)EMPTY;
  23    }
  24
  25    // singleton list
  26    public static <E> LinkedList<E> singleton(E e) {
  27        LinkedList<E> l = empty();
  28        return
  29            l.cons(e);
  30    }
  31
  32    // list from iterator
  33    public static <E> LinkedList<E> fromIterator(Iterator<E> elems) {
  34        if ( elems.hasNext() ) {
  35            E info = elems.next();
  36            return
  37                fromIterator(elems).cons(info);
  38        }
  39        return
  40            empty();
  41    }
  42
  43    //----------------------------------------
  44    // public methods
  45
  46    abstract public boolean       isEmpty();
  47    abstract public boolean       member(E e);
  48    abstract public int           length();
  49    abstract public E             head();
  50    abstract public LinkedList<E> tail();
  51    abstract public E             last();
  52    abstract public LinkedList<E> init();
  53    abstract public E             at(int i);
  54    /* destructive *
  55    abstract public LinkedList<E> copy();
  56    /**/
  57
  58    public LinkedList<E> append(E e) {
  59        return
  60            concat(singleton(e));
  61    }
  62
  63    public LinkedList<E> cons(E e) {
  64        return
  65            new Node<E>(ethis);
  66    }
  67
  68    abstract public LinkedList<E> concat(LinkedList<E> l2);
  69
  70    public LinkedList<E> reverse() {
  71        LinkedList<E> l = empty();
  72        return
  73            reverse1(l);
  74    }
  75    abstract protected LinkedList<E> reverse1(LinkedList<E> res)
  76
  77    public Iterator<E> iterator() {
  78        return
  79            new ListIterator<E>(this);
  80    }
  81
  82    public String toString() {
  83        return
  84            (new ListIterator<E>(this)).toString();
  85    }
  86
  87    //----------------------------------------
  88    // the empty list
  89
  90    // the "generic" empty list object, (the singleton has a raw type)
  91
  92    private static final LinkedList EMPTY
  93        = new Empty<Object>();
  94
  95    // the singleton class for the empty list object
  96
  97    private static final
  98        class Empty<E>
  99        extends LinkedList<E> {
 100
 101        public boolean isEmpty()   { return true;  }
 102        public boolean member(E e) { return false}
 103        public int     length()    { return 0;     }
 104
 105        public E head() {
 106            return undefined("head of empty list");
 107        }
 108        public LinkedList<E> tail() {
 109            return undefined("tail of empty list");
 110        }
 111        public E last() {
 112            return undefined("last of empty list");
 113        }
 114        public LinkedList<E> init() {
 115            return undefined("init of empty list");
 116        }
 117        public E at(int i) {
 118            return undefined("at of empty list");
 119        }
 120        public LinkedList<E> concat(LinkedList<E> l2) {
 121            return
 122                l2;
 123        }
 124        /* destructive *
 125        public LinkedList<E> copy() {
 126            return
 127                this;
 128        }
 129        /**/
 130
 131        //----------------------------------------
 132        // not public stuff
 133
 134        Empty() { }
 135
 136        protected LinkedList<E> reverse1(LinkedList<E> res) {
 137            return
 138                res;
 139        }
 140    }
 141
 142    //----------------------------------------
 143    // the none empty list class
 144
 145    private static final
 146        class Node<E>
 147        extends LinkedList<E> {
 148
 149        public boolean isEmpty()   { return false;  }
 150
 151        public boolean member(E e) {
 152            return
 153                e.equals(info)
 154                ||
 155                next.member(e);
 156        }
 157
 158        public int length() {
 159            return
 160                1 + next.length();
 161        }
 162
 163        public E head() {
 164            return
 165                info;
 166        }
 167
 168        public LinkedList<E> tail() {
 169            return
 170                next;
 171        }
 172
 173        public E last() {
 174            if ( next.isEmpty() )
 175                return
 176                    info;
 177            return
 178                next.last();
 179        }
 180
 181        public LinkedList<E> init() {
 182            if ( next.isEmpty() )
 183                return
 184                    empty();
 185            return
 186                setNext(next.init());
 187        }
 188
 189        public E at(int i) {
 190            if ( i == 0 )
 191                return
 192                    info;
 193            return
 194                next.at(i - 1);
 195        }
 196
 197        public LinkedList<E> concat(LinkedList<E> l2) {
 198            return
 199                setNext(next.concat(l2));
 200        }
 201
 202        /* destructive *
 203        public LinkedList<E> copy() {
 204            return
 205                next.copy().cons(info);
 206        }
 207        /**/
 208
 209        //----------------------------------------
 210        // not public stuff
 211
 212        private final E             info;
 213        private
 214            /* persistent */ final /**/
 215            LinkedList<E> next;
 216
 217        Node(E iLinkedList<E> n) {
 218            info = i;
 219            next = n;
 220            ++cntNode;
 221        }
 222
 223        protected LinkedList<E> reverse1(LinkedList<E> res) {
 224            LinkedList<E> tmp = next;
 225            return
 226                tmp.reverse1(setNext(res));
 227        }
 228
 229        LinkedList<E> setNext(LinkedList<E> next) {
 230            /* persistent */
 231            if ( next == this.next )
 232                return
 233                    this;
 234            return
 235                next.cons(info);
 236
 237            /* destructive *
 238            this.next = next;
 239            return
 240                this;
 241            /**/
 242        }
 243    }
 244
 245    //----------------------------------------
 246    // iterator class
 247
 248    private static
 249        class ListIterator<E>
 250        extends ds.util.Iterator<E> {
 251
 252        LinkedList<E> cur;
 253
 254        ListIterator(LinkedList<E> l) {
 255            cur = l;
 256            ++cntIter;
 257        }
 258
 259        public boolean hasNext() {
 260            return
 261                ! cur.isEmpty();
 262        }
 263
 264        public E next() {
 265            if ( cur.isEmpty() )
 266                return undefined("iterator exhausted");
 267            {
 268                E res = cur.head();
 269                cur   = cur.tail();
 270                return
 271                    res;
 272            }
 273        }
 274    }
 275
 276    //----------------------------------------
 277    // profiling
 278
 279    private static int cntNode = 0;
 280    private static int cntIter = 0;
 281
 282    public static String stats() {
 283        return
 284            "stats for ds.persistent.list.LinkedList:\n" +
 285            "# new Node()         : " + cntNode + "\n" +
 286            "# new ListIterator() : " + cntIter + "\n";
 287    }
 288}

Letzte Änderung: 15.10.2015
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel