homedukeAlgorithmen & Datenstrukturen mit Java: Beispielklasse für Mengen als verkettete Listen Prof. Dr. Uwe Schmidt FH Wedel

Beispielklasse für Mengen als verkettete Listen

weiter

weiter

Set
Schnittstelle
weiter
   1package ds.interfaces;
   2
   3/** Simple interface for sets */
   4
   5import java.util.Iterator;
   6
   7import ds.util.Invariant;
   8
   9import ds.util.E;  // example class for elements
  10
  11public
  12    interface Set
  13    extends Iterable<E>,
  14            Invariant {
  15
  16    boolean isEmpty();
  17    boolean member(E e);
  18    int     size();
  19    E       findMin();
  20    E       findMax();
  21    Set     insert(E e);
  22    Set     remove(E e);
  23    Set     union(Set m2);
  24    Set     difference(Set m2);
  25    Set     intersect(Set m2);
  26    Set     copy();
  27
  28    // inherited
  29
  30    // Iterator<E> iterator();
  31    // boolean inv();
  32}
weiter
Set
implementiert als sortierte einfach verkettete Liste
gleiche Datenstruktur wie bei List als verkettete Liste
ohne Generics
persistente Implementierung
destruktive Implementierung in Kommentar
weiter
   1package ds.persistent.set;
   2
   3/** Implementation of sets with ordered single linked lists.
   4
   5    Ordered linked lists require a total ordering
   6    on the elem domain.
   7
   8    This is a PERSISTENT implementation.
   9*/
  10
  11import ds.interfaces.Set;
  12
  13import ds.util.E;          // example class for elements
  14import ds.util.Invariant;
  15
  16import java.util.Iterator;
  17
  18import static java.lang.Integer.signum;
  19import static ds.util.Undef.undefined;
  20
  21public abstract
  22    class OrderedList
  23    implements Set {
  24
  25    //----------------------------------------
  26    // the smart constructors
  27
  28    // empty list
  29    public static OrderedList empty() {
  30        return
  31            EMPTY;
  32    }
  33
  34    // singleton list
  35    public static OrderedList singleton(E e) {
  36        return
  37            EMPTY.cons(e);
  38    }
  39
  40    // build search tree from arbitrary sequence (iterator)
  41    public static
  42        OrderedList fromIterator(Iterator<E> elems) {
  43
  44        OrderedList res = empty();
  45        while ( elems.hasNext() ) {
  46            E e = elems.next();
  47            res = res.insert(e);
  48        }
  49        return
  50            res;
  51    }
  52
  53    public abstract OrderedList insert(E e);
  54    public abstract OrderedList remove(E e);
  55    public abstract OrderedList union(Set m2);
  56    public abstract OrderedList intersect(Set m2);
  57    public abstract OrderedList difference(Set m2);
  58
  59    public Iterator<E> iterator() {
  60        ++cntIter;
  61        return
  62            new ListIterator(this);
  63    }
  64
  65    public OrderedList copy() {
  66        return
  67            this;
  68    }
  69
  70    //----------------------------------------
  71    // internal methods
  72
  73    // cons
  74    protected Node cons(E e) {
  75        return
  76            new Node(ethis);
  77    }
  78
  79    // access methods, only legal for Node objects
  80    // not defined for Empty object
  81
  82    Node        node() { return nodeExpected()}
  83    E           elem() { return nodeExpected()}
  84    OrderedList next() { return nodeExpected()}
  85
  86    private static <A> A nodeExpected() {
  87        return
  88            undefined("Node expected");
  89    }  
  90
  91    //----------------------------------------
  92    // the empty list implemented by applying the singleton design pattern
  93
  94    // the empty list object
  95
  96    private static final OrderedList EMPTY
  97        = new Empty();
  98
  99    // the singleton class for the empty list object
 100
 101    private static final
 102        class Empty
 103        extends OrderedList {
 104
 105        public boolean isEmpty() {
 106            return true;
 107        }
 108
 109        public boolean member(E e) {
 110            return false;
 111        }
 112
 113        public int size() {
 114            return 0;
 115        }
 116
 117        public E findMin() {
 118            nodeExpected();
 119            return null;
 120        }
 121  
 122        public E findMax() {
 123            nodeExpected();
 124            return null;
 125        }
 126
 127        public OrderedList insert(E e) {
 128            return
 129                singleton(e);
 130        }
 131
 132        public OrderedList remove(E e) {
 133            return
 134                this;
 135        }
 136
 137        public OrderedList union(Set m2) {
 138            return
 139                (OrderedList)m2;
 140        }
 141
 142        public OrderedList intersect(Set m2) {
 143            return
 144                this;
 145        }
 146
 147        public OrderedList difference(Set m2) {
 148            return
 149                this;
 150        }
 151
 152        public boolean inv() {
 153            return true;
 154        }
 155
 156        //----------------------------------------
 157        // not public stuff
 158
 159        Empty() { }
 160
 161    }
 162    
 163    //----------------------------------------
 164    // the node class for none empty trees
 165
 166    private static final
 167        class Node
 168        extends OrderedList {
 169
 170        /* persistent */
 171        final E           e;
 172        final OrderedList next;
 173
 174        /* destructive *
 175        E           e;
 176        OrderedList next;
 177        /**/
 178
 179        Node(E eOrderedList next) {
 180            assert e    != null;
 181            assert next != null;
 182
 183            this.e    = e;
 184            this.next = next;
 185            ++cntNode;
 186        }
 187
 188        //----------------------------------------
 189        // predicates and attributes
 190
 191        public boolean isEmpty() {
 192            return false;
 193        }
 194
 195        public boolean member(E e) {
 196            assert e != null;
 197
 198            switch (signum(e.compareTo(this.e))) {
 199            case -1:
 200                return
 201                    false;
 202            case 0:
 203                return
 204                    true;
 205            case +1:
 206                return
 207                    next.member(e);
 208            }
 209            // never executed, but required by javac
 210            return
 211                false;
 212        }
 213
 214        public int size() {
 215            return
 216                1 + next.size();
 217        }
 218
 219        public E findMin() {
 220            return e;
 221        }  
 222
 223        public E findMax() {
 224            if ( next.isEmpty() )
 225                return e;
 226            return
 227                next.findMax();
 228        }  
 229
 230        public boolean inv() {
 231            if ( next.isEmpty() )
 232                return
 233                    true;
 234            return
 235                e.compareTo(next.elem()) < 0
 236                &&
 237                next.inv();
 238        }
 239
 240        //----------------------------------------
 241        // internal methods
 242
 243        Node        node() { return this}
 244        E           elem() { return e;    }
 245        OrderedList next() { return next}
 246
 247        // setter
 248
 249        private Node setNext(OrderedList next) {
 250            /* persistent */
 251            if ( next == this.next )
 252                return
 253                    this;
 254            return
 255                next.cons(this.e);
 256
 257            /* destructive *
 258            this.next = next;
 259            return
 260                this;
 261            /**/
 262        }
 263
 264        //----------------------------------------
 265
 266        public OrderedList insert(E e) {
 267            assert e != null;
 268
 269            switch ( signum(e.compareTo(this.e)) ) {
 270            case -1: // add to the front
 271                return
 272                    this.cons(e);
 273            case 0: // already there
 274                return
 275                    this;
 276            case +1: // continue search
 277                return
 278                    setNext(next.insert(e));
 279            }
 280            // never executed, but required by javac
 281            return
 282                null;
 283        }
 284    
 285        public OrderedList remove(E e) {
 286            assert e != null;
 287
 288            switch ( signum(e.compareTo(this.e)) ) {
 289            case -1: // not there: nothing to remove
 290                return
 291                    this;
 292            case 0: // found: remove head of list
 293                return
 294                    next;
 295            case +1: // continue search
 296                return
 297                    setNext(next.remove(e));
 298            }
 299            // never executed, but required by javac
 300            return
 301                null;
 302        }
 303
 304        public OrderedList union(Set m2) {
 305            assert m2 != null;
 306
 307            OrderedList l2 = (OrderedList)m2;
 308
 309            if ( l2.isEmpty() )
 310                return
 311                    this;
 312
 313            Node n2 = l2.node();
 314            switch ( signum(n2.e.compareTo(this.e)) ) {
 315
 316            case -1: // add head of m2 to the front of the result
 317                return
 318                    n2.setNext(union(n2.next));
 319
 320            case 0: // same elem, ignore head of m2
 321                return
 322                    setNext(next.union(n2.next));
 323
 324            case +1: // add head to the result and merge tail with m2
 325                return
 326                    setNext(next.union(m2));
 327            }
 328            // never executed, but required by javac
 329            return
 330                null;
 331        }
 332
 333        public OrderedList intersect(Set m2) {
 334            assert m2 != null;
 335
 336            OrderedList l2 = (OrderedList)m2;
 337
 338            if ( l2.isEmpty() )
 339                return
 340                    l2;
 341
 342            Node n2 = l2.node();
 343            switch ( signum(n2.e.compareTo(this.e)) ) {
 344
 345            case -1: // ignore head of m2
 346                return
 347                    intersect(n2.next);
 348
 349            case 0: // head remains in result
 350                return
 351                    setNext(next.intersect(n2.next));
 352
 353            case +1: // ignore head
 354                return
 355                    next.intersect(m2);
 356            }
 357            // never executed, but required by javac
 358            return
 359                null;
 360        }
 361
 362        public OrderedList difference(Set m2) {
 363            assert m2 != null;
 364
 365            OrderedList l2 = (OrderedList)m2;
 366
 367            if ( l2.isEmpty() ) // nothing to do
 368                return
 369                    this;
 370
 371            Node n2 = l2.node();
 372            switch ( signum(n2.e.compareTo(this.e)) ) {
 373
 374            case -1: // ignore head of m2
 375                return
 376                    difference(n2.next);
 377
 378            case 0: // same elem, remove elem
 379                return
 380                    next.difference(n2.next);
 381
 382            case +1: // take head as it is and continue
 383                return
 384                    setNext(next.difference(m2));
 385            }
 386            // never executed, but required by javac
 387            return
 388                null;
 389        }
 390
 391        /* destructive *
 392        public OrderedList copy() {
 393            return
 394                next.copy().cons(e);
 395        }
 396        /**/
 397    }
 398    
 399    //----------------------------------------
 400    // iterators
 401
 402    // ascending enumeration
 403
 404    private static
 405        class ListIterator
 406        extends ds.util.Iterator<E> {
 407        
 408        OrderedList queue;
 409
 410        ListIterator(OrderedList n) {
 411            assert n != null;
 412
 413            queue = n;
 414            ++cntIter;
 415        }
 416
 417        public boolean hasNext() {
 418            return
 419                ! queue.isEmpty();
 420        }
 421
 422        public E next() {
 423            if ( queue.isEmpty() )
 424                return
 425                    undefined("empty list");
 426
 427            Node n = queue.node();
 428            queue  = queue.next();
 429            return
 430                n.e;
 431        }
 432    }
 433
 434    //----------------------------------------
 435    // profiling
 436
 437    private static int cntNode = 0;
 438    private static int cntIter = 0;
 439
 440    public static String stats() {
 441        return
 442            "stats for ds.persistent.set.OrderedList:\n" +
 443            "# new Node()               : " + cntNode + "\n" +
 444            "# new Iterator()           : " + cntIter + "\n";
 445    }
 446
 447    public String objStats() {
 448        int s = size();
 449        int o = s;
 450        int f = 2 * s;
 451        int m = o + f;
 452
 453        return
 454            "mem stats for ds.persistent.set.OrderedList object:\n" +
 455            "# elements (size)      : " + s + "\n" +
 456            "# objects              : " + o + "\n" +
 457            "# fields               : " + f + "\n" +
 458            "# mem words            : " + m + "\n";
 459    }
 460}
weiter
Quellen
weiter

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