Last active
August 29, 2015 14:19
-
-
Save sheniff/bf940a746eda816310c4 to your computer and use it in GitHub Desktop.
Linked lists in JS... Useful but only for very specific cases (they kick array's ass in prepending items, as expected)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// LinkedListNode Class (Module pattern with cached functions) | |
!function(){ | |
LinkedListNode = function LinkedListNode(data) { | |
this.node = [data, null]; | |
} | |
LinkedListNode.prototype.getNext = getNext; | |
LinkedListNode.prototype.getData = getData; | |
LinkedListNode.prototype.setNext = setNext; | |
LinkedListNode.prototype.setData = setData; | |
function getNext() { | |
return this.node[1]; | |
} | |
function getData() { | |
return this.node[0]; | |
} | |
function setNext(node) { | |
this.node[1] = node; | |
} | |
function setData(data) { | |
this.node[0] = data; | |
} | |
}() | |
// LinkedList Class (Module pattern with cached functions) | |
!function(){ | |
LinkedList = function LinkedList() { | |
this.list = null; | |
this.last = null; | |
}; | |
LinkedList.prototype.print = print; | |
LinkedList.prototype.append = append; | |
LinkedList.prototype.prepend = prepend; | |
LinkedList.prototype.remove = remove; | |
LinkedList.prototype.removeLast = removeLast; | |
function print() { | |
if (this.list) { | |
var current = this.list, | |
result = ''; | |
while (current !== null) { | |
result += ' ~> ' + current.getData(); | |
current = current.getNext(); | |
} | |
console.log(result); | |
} | |
} | |
function append(data) { | |
var node = new LinkedListNode(data); | |
if(this.last === null) { | |
this.list = node; | |
} else { | |
this.last.setNext(node); | |
} | |
return this.last = node; | |
} | |
function prepend(data) { | |
var node = new LinkedListNode(data); | |
node.setNext(this.list); | |
return this.list = node; | |
} | |
function remove(node) { | |
if(typeof(node) === 'number') { | |
// removing by position | |
var prev = this.list, | |
i = 0; | |
for(; i < node - 1 && prev !== null; i++) { | |
prev = prev.getNext(); | |
} | |
if(prev !== null && prev.getNext() !== null) { | |
prev.setNext(prev.getNext().getNext()); | |
} | |
} else if(node instanceof LinkedListNode) { | |
// removing a node | |
var nxt = node.getNext(); | |
if(nxt !== null) { | |
node.setData(nxt.getData()); | |
node.setNext(nxt.getNext()); | |
} else { | |
this.removeLast(); | |
} | |
} else { | |
console.error('Invalid element to remove'); | |
} | |
} | |
function removeLast() { | |
var target = this.list; | |
if(target !== null) { | |
if(target.getNext() === null) { | |
this.list = null; | |
} else { | |
while(target.getNext().getNext() !== null) { | |
target = target.getNext(); | |
} | |
target.setNext(null); | |
} | |
} | |
} | |
}() | |
// Testing it out! | |
function vageTest() { | |
var list = new LinkedList(); | |
var toRemove = list.append('bar'); | |
list.append('baz'); | |
list.prepend('foo'); | |
list.append('another'); | |
list.append('removed'); | |
list.append('node'); | |
list.remove(toRemove); | |
list.remove(3); | |
list.removeLast(); | |
list.print(); | |
} | |
function efficiencyTestPrepend(ELEMENTS) { | |
var list = new LinkedList(); | |
var arr = new Array(); | |
var i, start, end, deltaArray, deltaList; | |
ELEMENTS = ELEMENTS || 10000; | |
// array case | |
start = new Date(); | |
for (i = 0; i < ELEMENTS; i++) { | |
arr.splice(0,0,i); | |
} | |
end = new Date(); | |
deltaArray = end.getTime() - start.getTime(); | |
// list case | |
start = new Date(); | |
for (i = 0; i < ELEMENTS; i++) { | |
list.prepend(i); | |
} | |
end = new Date(); | |
deltaList = end.getTime() - start.getTime(); | |
console.log('Efficiency Test: Prepend ' + ELEMENTS + ' items.'); | |
console.log('Array:\t\t' + deltaArray + 'ms'); | |
console.log('LinkedList:\t' + deltaList + 'ms'); | |
} | |
function efficiencyTestAppend(ELEMENTS) { | |
var list = new LinkedList(); | |
var arr = new Array(); | |
var i, start, end, deltaArray, deltaList; | |
ELEMENTS = ELEMENTS || 10000; | |
// array case | |
start = new Date(); | |
for (i = 0; i < ELEMENTS; i++) { | |
arr.push(i); | |
} | |
end = new Date(); | |
deltaArray = end.getTime() - start.getTime(); | |
// list case | |
start = new Date(); | |
for (i = 0; i < ELEMENTS; i++) { | |
list.append(i); | |
} | |
end = new Date(); | |
deltaList = end.getTime() - start.getTime(); | |
console.log('Efficiency Test: Append ' + ELEMENTS + ' items.'); | |
console.log('Array:\t\t' + deltaArray + 'ms'); | |
console.log('LinkedList:\t' + deltaList + 'ms'); | |
} | |
vageTest(); | |
efficiencyTestPrepend(10000); | |
efficiencyTestAppend(1000000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment