Here is my implementation of double linked list. Is it possible to reduce the code and improve it?
Some methods here:
- head (returns head of the list) tail (returns tail of the list);
- append (param: new data; add new item to the end of the list);
- deleteAt (param: index; deletes item by index; error handling)
- at(returns item by index; error handling)
- insertAt (inserts item by index; new item should be placed at the specified index)
- reverse (rearranges the list's items back-to-front)
- each (param: function; applies specified function to each item of the list)
- indexOF(param: item; return index of the specified item (first entry))
function List() {
this.length = 0;
this._head = null;
this._tail = null;
}
List.prototype = {
head: function() {
if (this.length > 0) {
return this._head;
} else {
throw new Error("List has zero length.");
}
},
tail: function() {
if (this.length > 0) {
return this._tail;
} else {
throw new Error("List has zero length.");
}
},
append: function(value) {
var node = {
value: value,
next: null,
prev: null,
}
if (this.length == 0) {
this._head = node;
this._tail = node;
} else {
this._tail.next = node;
node.prev = this._tail;
this._tail = node;
}
this.length++;
return this;
},
deleteAt: function(index) {
if (index < this.length) {
var node = this._head;
var i = 0;
while (i < index) {
node = node.next;
i++;
}
while (i != this.length - 1) {
node.value = node.next.value;
this._tail = node;
node = node.next;
i++;
}
node.value = null;
node.next = null;
this.length--;
return this;
} else {
throw new Error("The index of the item that you have selected more than the length of the list.");
}
},
at: function (index) {
return this._at(index).value;
},
_at: function(index) {
if (this.length < index) {
throw new Error("The index of the item that you have selected more than the length of the list.");
} else {
var node = this._head;
var i = 0;
while (i != index) {
node = node.next;
i++;
}
return node;
}
},
insertAt: function(index, value) {
if (index < this.length) {
var node = {
value: value,
next: null,
prev: null,
}
var nodeCur = this._at(index);
var nodePrev = nodeCur.prev;
var nodeNext = nodeCur.next;
node.prev = nodePrev;
node.next = nodeNext;
nodePrev.next = node;
nodeNext.prev = node;
this.length++;
return this;
} else {
throw new Error("The index of the item that you have selected more than the length of the list.");
}
},
reverse: function() {
var node_buf = {
value: null,
next: null,
prev: null,
}
var node_head = this._head;
var node_tail = this._tail;
var i = 0;
while (i < Math.floor(this.length / 2)) {
node_buf.value = node_tail.value;
node_tail.value = node_head.value;
node_head.value = node_buf.value;
node_head = node_head.next;
node_tail = node_tail.prev;
i++;
}
return this;
},
each: function(callback) {
var node = this._head;
var i = 0;
while (i < this.length) {
node.value = callback(node.value);
i++;
node = node.next;
}
return this;
},
indexOF: function(value) {
var node = this._head;
var i = 0;
while (i != this.length) {
if (node.value == value) {
return i;
}
node = node.next;
i++;
}
throw new Error("Value " + value + " is not found.");
}
};