homedukeAlgorithmen & Datenstrukturen mit Java: Beispielklasse für einfach verkettete Ringe Prof. Dr. Uwe Schmidt FH Wedel

Beispielklasse für einfach verkettete Ringe

weiter

weiter

LinkedRing.java

List
implementiert als einfach verketteter Ring
nur destruktive Implementierung möglich
ohne Generics
weiter
   1package ds.destructive.list;
   2
   3/** A linked ring is an efficient implementation
   4    for FIFO buffers (queues).
   5
   6    A ring is always a destructive data structure,
   7    every modifying operation changes some references
   8    in the LinkedRing objects.
   9 */
  10
  11import ds.interfaces.List;
  12import ds.util.NullIterator;
  13import ds.util.E;
  14import java.util.Iterator;
  15
  16import static ds.util.Undef.undefined;
  17
  18public abstract class LinkedRing
  19    implements List {
  20
  21    //----------------------------------------
  22    // the smart constructors
  23
  24    // empty ring
  25    public static LinkedRing empty() {
  26        return
  27            EMPTY;
  28    }
  29
  30    // singleton ring
  31    public static LinkedRing singleton(E e) {
  32        return
  33            new Node(e);
  34    }
  35
  36    // list from iterator
  37    public static LinkedRing fromIterator(Iterator<E> elems) {
  38        LinkedRing acc = empty();
  39        while ( elems.hasNext() ) {
  40            E info = elems.next();
  41            acc = acc.append(info);
  42        }
  43        return
  44            acc;
  45    }
  46
  47    //----------------------------------------
  48
  49    public boolean inv() {
  50        return
  51            true;
  52    }
  53
  54    public abstract LinkedRing concat(List l2);
  55
  56    public LinkedRing append(E e) {
  57        return
  58            this.concat(singleton(e));
  59    }
  60
  61    public LinkedRing cons(E e) {
  62        return
  63            singleton(e).concat(this);
  64    }
  65
  66    //----------------------------------------
  67    // generally usable methods
  68    // working with iterators
  69
  70    public E at(int i) {
  71        Iterator<E> xs = iterator();
  72        while ( i != 0 ) {
  73            xs.next();
  74            --i;
  75        }
  76        return
  77            xs.next();
  78    }
  79
  80    public boolean member(E e) {
  81        for (E x : this)
  82            if ( e.equalTo(x) )
  83                return
  84                    true;
  85        return
  86            false;
  87    }
  88
  89    public int length() {
  90        int res = 0;
  91        for (E x : this)
  92            ++res;
  93        return
  94            res;
  95    }
  96
  97    public LinkedRing copy() {
  98        LinkedRing res = empty();
  99        for (E x : this)
 100            res = res.append(x);
 101        return
 102            res;
 103    }
 104
 105    public String toString() {
 106        return
 107            iterator().toString();
 108    }
 109
 110    //----------------------------------------
 111    // the empty ring
 112
 113    // the "generic" empty ring object
 114
 115    private static final LinkedRing EMPTY
 116        = new Empty();
 117
 118    // the singleton class for the empty list object
 119
 120    private static final
 121        class Empty
 122        extends LinkedRing {
 123
 124        public boolean isEmpty() {
 125            return true;
 126        }
 127
 128        public boolean member(E e) {
 129            return false;
 130        }
 131
 132        public int length() {
 133            return 0;
 134        }
 135
 136        public E head() {
 137            return
 138                undefined("head of empty list");
 139        }
 140
 141        public LinkedRing tail() {
 142            return
 143                undefined("tail of empty list");
 144        }
 145
 146        public E last() {
 147            return
 148                undefined("last of empty list");
 149        }
 150
 151        public LinkedRing init() {
 152            return
 153                undefined("init of empty list");
 154        }
 155
 156        public LinkedRing concat(List l2) {
 157            // only linked rings are allowed for l2
 158            return
 159                (LinkedRing)l2;
 160        }
 161        public LinkedRing reverse() {
 162            return
 163                this;
 164        }
 165        public LinkedRing copy() {
 166            return
 167                this;
 168        }
 169
 170        public Iterator<E> iterator() {
 171            ++cntIter;
 172            return
 173                new NullIterator<E>();
 174        }
 175
 176        //----------------------------------------
 177        // not public stuff
 178
 179        Empty() { }
 180    }
 181
 182    // downcast from LinkedRing to Node
 183    Node node() {
 184        return
 185            undefined("Node expected");
 186    }
 187
 188    //----------------------------------------
 189    // the none empty list class
 190
 191    private static final
 192        class Node
 193        extends LinkedRing {
 194
 195        public boolean isEmpty() {
 196            return false;
 197        }
 198
 199        public E head() {
 200            return
 201                next.info;
 202        }
 203
 204        public LinkedRing tail() {
 205            if ( next == this ) // singleton ring
 206                return
 207                    empty();
 208            next = next.next;
 209            return
 210                this;
 211        }
 212
 213        public E last() {
 214            return
 215                info;
 216        }
 217
 218        public LinkedRing init() {
 219            if ( next == this ) // singleton ring
 220                return
 221                    empty();
 222
 223            // search the node in front of this
 224            Node cur = this.next.node();
 225            while ( cur.next != this ) {
 226                cur = cur.next.node();
 227            }
 228            cur.next = this.next;
 229            return
 230                cur;
 231        }
 232
 233        public LinkedRing concat(List l2) {
 234            // only linked rings are allowed for l2
 235            LinkedRing r2 = (LinkedRing)l2;
 236
 237            if ( r2.isEmpty() )
 238                return
 239                    this;
 240
 241            Node n2   = r2.node();
 242            Node  t   = n2.next;
 243            n2  .next = next;
 244            this.next = t;
 245            return
 246                n2;
 247        }
 248
 249        public LinkedRing reverse() {
 250            Node cur = this.next.node();
 251            Node prv = this;
 252            while ( cur != this ) {
 253                Node tmp = cur.next.node();
 254                cur.next = prv;
 255                prv      = cur;
 256                cur      = tmp;
 257            }
 258            Node res = this.next;
 259            this.next = prv;
 260            return
 261                res;
 262        }
 263
 264        public Iterator<E> iterator() {
 265            ++cntIter;
 266            return
 267                new NodeIterator(this);
 268        }
 269
 270        //----------------------------------------
 271        // not public stuff
 272
 273        private E    info;
 274        private Node next;
 275
 276        Node(E e) {
 277            info = e;
 278            next = this;
 279            ++cntNode;
 280        }
 281
 282        // downcast from LinkedRing to Node
 283        Node node() {
 284            return this;
 285        }
 286
 287        // iterator for none empty rings
 288        private static final
 289            class NodeIterator
 290            extends ds.util.Iterator<E> {
 291
 292            Node    r;
 293            Node    cur;
 294            boolean first;
 295
 296            NodeIterator(Node r) {
 297                this.r     = r;
 298                this.cur   = r;
 299                this.first = true;
 300            }
 301
 302            public boolean hasNext() {
 303                return
 304                    first || r != cur;
 305            }
 306
 307            public E next() {
 308                if ( ! hasNext() )
 309                    return
 310                        undefined("ring exhausted");
 311
 312                first = false;
 313                cur   = cur.next;
 314                return
 315                    cur.info;
 316            }
 317        }
 318    }
 319
 320    //----------------------------------------
 321    // profiling
 322
 323    private static int cntNode = 0;
 324    private static int cntIter = 0;
 325
 326    public static String stats() {
 327        return
 328            "stats for ds.destructive.list.LinkedRing:\n" +
 329            "# new Node()         : " + cntNode + "\n" +
 330            "# new ListIterator() : " + cntIter + "\n";
 331    }
 332}
weiter
Quellen
weiter

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