OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * A doubly-linked list, adapted from DoubleLinkedQueueEntry in |
| 7 * sdk/lib/collection/queue.dart. |
| 8 */ |
| 9 // TODO(jmesserly): this should be in a shared pkg somewhere. Surely I am not |
| 10 // the only person who will want to use a linked list :) |
| 11 library linked_list; |
| 12 |
| 13 /** |
| 14 * An entry in a doubly linked list. It contains a pointer to the next |
| 15 * entry, the previous entry, and the boxed value. |
| 16 */ |
| 17 class LinkedListNode<E> { |
| 18 LinkedListNode<E> _previous; |
| 19 LinkedListNode<E> _next; |
| 20 E _value; |
| 21 |
| 22 LinkedListNode._(E e) { |
| 23 _value = e; |
| 24 } |
| 25 |
| 26 void _link(LinkedListNode<E> p, LinkedListNode<E> n) { |
| 27 _next = n; |
| 28 _previous = p; |
| 29 p._next = this; |
| 30 n._previous = this; |
| 31 } |
| 32 |
| 33 LinkedListNode<E> append(E e) => |
| 34 new LinkedListNode<E>._(e).._link(this, _next); |
| 35 |
| 36 LinkedListNode<E> prepend(E e) => |
| 37 new LinkedListNode<E>._(e).._link(_previous, this); |
| 38 |
| 39 void remove() { |
| 40 _previous._next = _next; |
| 41 _next._previous = _previous; |
| 42 _next = null; |
| 43 _previous = null; |
| 44 } |
| 45 |
| 46 LinkedListNode<E> get _nonSentinel => this; |
| 47 |
| 48 LinkedListNode<E> get previous => _previous._nonSentinel; |
| 49 |
| 50 LinkedListNode<E> get next => _next._nonSentinel; |
| 51 |
| 52 E get value => _value; |
| 53 |
| 54 set value(E e) => _value = e; |
| 55 } |
| 56 |
| 57 /** |
| 58 * A sentinel in a double linked list is used to manipulate the list |
| 59 * at both ends. A double linked list has exactly one sentinel, which |
| 60 * is the only entry when the list is constructed. Initially, a |
| 61 * sentinel has its next and previous entry point to itself. A |
| 62 * sentinel does not box any user value. |
| 63 */ |
| 64 class LinkedListSentinel<E> extends LinkedListNode<E> { |
| 65 LinkedListSentinel() : super._(null) { |
| 66 _link(this, this); |
| 67 } |
| 68 |
| 69 void remove() { |
| 70 throw new StateError("Empty list"); |
| 71 } |
| 72 |
| 73 LinkedListNode<E> get _nonSentinel => null; |
| 74 |
| 75 void set value(E e) { |
| 76 throw new StateError("Empty list"); |
| 77 } |
| 78 |
| 79 E get value { |
| 80 throw new StateError("Empty list"); |
| 81 } |
| 82 } |
OLD | NEW |