UNPKG

blossom

Version:

Modern, Cross-Platform Application Framework

199 lines (177 loc) 4.1 kB
/*! * JavaScript LinkedList * * Licensed under the new BSD License. * Copyright 2008-2009, Bram Stein * All rights reserved. */ sc_require('text/object'); function LinkedList() { this.head = null; this.tail = null; this.listSize = 0; } (function () { Object.extend(LinkedList, { Node: function (data) { this.prev = null; this.next = null; this.data = data; } }); Object.extend(LinkedList.Node.prototype, { toString: function () { return this.data.toString(); } }); function isLinked(list, node) { return !((node && node.prev === null && node.next === null && list.tail !== node && list.head !== node) || list.isEmpty()); } Object.extend(LinkedList.prototype, { size: function () { return this.listSize; }, isEmpty: function () { return this.listSize === 0; }, first: function () { return this.head; }, last: function () { return this.last; }, toString: function () { return this.toArray().toString(); }, toArray: function () { var node = this.head, result = []; while (node !== null) { result.push(node); node = node.next; } return result; }, // Note that modifying the list during // iteration is not safe. forEach: function (fun) { var node = this.head; while (node !== null) { fun(node); node = node.next; } }, contains: function (n) { var node = this.head; if (!isLinked(this, n)) { return false; } while (node !== null) { if (node === n) { return true; } node = node.next; } return false; }, at: function (i) { var node = this.head, index = 0; if (i >= this.listLength || i < 0) { return null; } while (node !== null) { if (i === index) { return node; } node = node.next; index += 1; } return null; }, insertAfter: function (node, newNode) { if (!isLinked(this, node)) { return this; } newNode.prev = node; newNode.next = node.next; if (node.next === null) { this.tail = newNode; } else { node.next.prev = newNode; } node.next = newNode; this.listSize += 1; return this; }, insertBefore: function (node, newNode) { if (!isLinked(this, node)) { return this; } newNode.prev = node.prev; newNode.next = node; if (node.prev === null) { this.head = newNode; } else { node.prev.next = newNode; } node.prev = newNode; this.listSize += 1; return this; }, push: function (node) { if (this.head === null) { this.unshift(node); } else { this.insertAfter(this.tail, node); } return this; }, unshift: function (node) { if (this.head === null) { this.head = node; this.tail = node; node.prev = null; node.next = null; this.listSize += 1; } else { this.insertBefore(this.head, node); } return this; }, remove: function (node) { if (!isLinked(this, node)) { return this; } if (node.prev === null) { this.head = node.next; } else { node.prev.next = node.next; } if (node.next === null) { this.tail = node.prev; } else { node.next.prev = node.prev; } this.listSize -= 1; return this; }, pop: function () { var node = this.tail; this.tail.prev.next = null; this.tail = this.tail.prev; this.listSize -= 1; node.prev = null; node.next = null; return node; }, shift: function () { var node = this.head; this.head.next.prev = null; this.head = this.head.next; this.listSize -= 1; node.prev = null; node.next = null; return node; } }); }());