Skip to content

Instantly share code, notes, and snippets.

@sheniff
Last active August 29, 2015 14:19
Show Gist options
  • Save sheniff/bf940a746eda816310c4 to your computer and use it in GitHub Desktop.
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)
// 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