Skip to content

Instantly share code, notes, and snippets.

@travisperson
Created May 10, 2012 04:45
Show Gist options
  • Save travisperson/2651075 to your computer and use it in GitHub Desktop.
Save travisperson/2651075 to your computer and use it in GitHub Desktop.
Start of a implementation of a doubly linked list in javascript
List = function (debug) {
var self = this
if ( debug == true)
self._debug = debug
self._size = 0;
self._head = null;
self._tail = null;
self._node_id = 0;
self._makeNode = function (data)
{
var node = {
_data : data
, _next : null
, _prev : null
, _id : self._node_id++
, Data : function () { return this._data }
, Next : function () { return this._next }
, Prev : function () { return this._prev }
}
return node
}
self._insert_at = function ( /*<Node>*/ position_node, /*<Node>*/ new_node )
{
new_node._prev = position_node._prev
new_node._next = position_node
if ( position_node._prev != null )
position_node._prev._next = new_node
position_node._prev = new_node
if (position_node._id == self._head._id)
self._head = new_node
self._size++
}
self._remove_at = function ( /*<Node>*/ position_node )
{
if ( position_node._prev != null )
position_node._prev._next = position_node._next
if ( position_node._next != null )
position_node._next._prev = position_node._prev
if ( position_node._id == self._head._id )
self._head = position_node._next
self._size--
}
self._traverse = function ( fc, node, o ) {
if ( node._id != 0 )
{
// If the function returns false, exit
if ( fc( node, o ) == false ) return
// Move to the next node
if ( node._next != null )
self._traverse( fc, node._next, o )
}
}
var node = self._makeNode(null);
self._head = node
self._tail = node
return self
}
List.prototype = {
// Push to front of list
push_front : new Function /* ( <Object> data) */
// Push to back of list
, push_back : new Function /* ( <Object> data) */
// Pop from front of list
, pop_front : new Function /* () */
// Pop from back of list
, pop_back : new Function /* () */
// Insert data using the passed in function to find the correct location
, insert : new Function /* ( <Function> fc, <Object> data) */
// Remove the passed in node from the list
, erase : new Function /* ( <Node> node) */
// Return the size of the list
, size : new Function /* () */
// Sorts the list via the passed in function
, sort : new Function /* ( <Function> sort) */
// Clear the list
, clear : new Function /* () */
// Traverses the list
, traverse : new Function /* ( <Function> fc, <Object> collector ) */
}
List.prototype.push_front = function (data)
{
var self = this
var node = self._makeNode(data)
self._insert_at ( self._head, node )
if (self._debug) console.log("Push Front [", data, "]")
}
List.prototype.push_back = function (data)
{
var self = this
var node = self._makeNode(data)
self._insert_at ( self._tail, node )
if (self._debug) console.log("Push Back [", data, "]")
}
List.prototype.pop_front = function ()
{
var self = this
if ( self._size == 0 ) return
self._remove_at ( self._head )
if (self._debug) console.log("Pop Front")
}
List.prototype.pop_back = function ()
{
var self = this
if ( self._size == 0 ) return
self._remove_at ( self._tail._prev )
if (self._debug) console.log("Pop Back")
}
List.prototype.traverse = function ( fc )
{
var self = this
var o = {}
self._traverse( fc, self._head, o )
return o;
}
var print_list = function (node, collection) {
if ( typeof collection.nodes == "undefined" )
collection.nodes = []
collection.nodes.push(node.Data());
return true;
}
l = new List(true)
l.push_front( 'b' )
l.push_back( 'c' )
l.push_front( 'a' )
l.push_back( 'd' )
console.log("Print", l.traverse(print_list))
l.pop_front()
console.log("Print", l.traverse(print_list))
l.pop_back()
console.log("Print", l.traverse(print_list))
Push Front [ b ]
Push Back [ c ]
Push Front [ a ]
Push Back [ d ]
Print { nodes: [ 'a', 'b', 'c', 'd' ] }
Pop Front
Print { nodes: [ 'b', 'c', 'd' ] }
Pop Back
Print { nodes: [ 'b', 'c' ] }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment