123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import defined from './defined.js';
- import defineProperties from './defineProperties.js';
- /**
- * @private
- */
- function DoublyLinkedList() {
- this.head = undefined;
- this.tail = undefined;
- this._length = 0;
- }
- defineProperties(DoublyLinkedList.prototype, {
- length : {
- get : function() {
- return this._length;
- }
- }
- });
- /**
- * @private
- */
- function DoublyLinkedListNode(item, previous, next) {
- this.item = item;
- this.previous = previous;
- this.next = next;
- }
- /**
- * Adds the item to the end of the list
- * @param {*} [item]
- * @return {DoublyLinkedListNode}
- */
- DoublyLinkedList.prototype.add = function(item) {
- var node = new DoublyLinkedListNode(item, this.tail, undefined);
- if (defined(this.tail)) {
- this.tail.next = node;
- this.tail = node;
- } else {
- this.head = node;
- this.tail = node;
- }
- ++this._length;
- return node;
- };
- function remove(list, node) {
- if (defined(node.previous) && defined(node.next)) {
- node.previous.next = node.next;
- node.next.previous = node.previous;
- } else if (defined(node.previous)) {
- // Remove last node
- node.previous.next = undefined;
- list.tail = node.previous;
- } else if (defined(node.next)) {
- // Remove first node
- node.next.previous = undefined;
- list.head = node.next;
- } else {
- // Remove last node in the linked list
- list.head = undefined;
- list.tail = undefined;
- }
- node.next = undefined;
- node.previous = undefined;
- }
- /**
- * Removes the given node from the list
- * @param {DoublyLinkedListNode} node
- */
- DoublyLinkedList.prototype.remove = function(node) {
- if (!defined(node)) {
- return;
- }
- remove(this, node);
- --this._length;
- };
- /**
- * Moves nextNode after node
- * @param {DoublyLinkedListNode} node
- * @param {DoublyLinkedListNode} nextNode
- */
- DoublyLinkedList.prototype.splice = function(node, nextNode) {
- if (node === nextNode) {
- return;
- }
- // Remove nextNode, then insert after node
- remove(this, nextNode);
- var oldNodeNext = node.next;
- node.next = nextNode;
- // nextNode is the new tail
- if (this.tail === node) {
- this.tail = nextNode;
- } else {
- oldNodeNext.previous = nextNode;
- }
- nextNode.next = oldNodeNext;
- nextNode.previous = node;
- };
- export default DoublyLinkedList;
|