How would I go about creating a tree-like data structure in JS, where, I can have access to things like reference to parent node, id based node lookup, having access to length (number) of children nodes, index based lookup etc?
this is basically the API I am envisioning:
var rootNode = DataStructure.getRoot();
var child1 = rootNode.addNode('child1'); //added a node with id 'child1'
child1.addNode('innerChild1');
child1.addNode('innerChild2');
rootNode.getChildById('child1') //should be same node as var child1
rootNode.getAtIndex(0) //should be same node as var child1
child1.parent() //should be rootNode
child1.getAtIndex(0) // should be node with id 'innerChild1'
child1.getAtIndex(1) // should be node with id 'innerChild2'
child1.length() //should be 2
etc..
I understand its a broad question, but I wonder if anyone could recommend a way to approach this and/or any libraries that might be doing it already? Should i just dynamically create an XML and work with its native methods? Would that be the fastest ?
Array is a good static data structure that can be accessed randomly and is fairly easy to implement. Linked Lists on the other hand is dynamic and is ideal for application that requires frequent operations such as add, delete, and update.
Definition. A tree is a data structure consisting of a set of linked nodes that represent a hierarchical tree structure. Each node is linked to others via parent-children relationship. The first node in the tree is the root, whereas nodes without any children are the leaves.
A tree is a non linear data structure. A Binary Search tree is a binary tree in which nodes that have lesser value are stored on the left while the nodes with a higher value are stored at the right. Now let's see an example of a Binary Search Tree node: Javascript.
The data structure you described can be easily implemented as follows:
var Tree = defclass({
constructor: function (parent) {
this.parent = parent || null; // null for root node
this.children = {}; // for id based lookup
this.ids = []; // for index based lookup
this.length = 0; // for ease of access
},
addNode: function (id) {
var children = this.children;
if (children.hasOwnProperty(id)) throw new Error(id + " exists");
return children[this.ids[this.length++] = id] = new Tree(this);
},
getChildById: function (id) {
var children = this.children;
if (children.hasOwnProperty(id)) return children[id];
throw new Error(id + " does not exist");
},
getAtIndex: function (index) {
return this.getChildById(this.ids[index]);
}
});
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
<script>
setTimeout(function () {
var rootNode = new Tree;
var child1 = rootNode.addNode("child1");
var innerChild1 = child1.addNode("innerChild1");
var innerChild2 = child1.addNode("innerChild2");
console.assert(rootNode.getChildById("child1") === child1);
console.assert(rootNode.getAtIndex(0) === child1);
console.assert(child1.parent === rootNode);
console.assert(child1.getAtIndex(0) === innerChild1);
console.assert(child1.getAtIndex(1) === innerChild2);
console.assert(child1.length === 2);
alert("success");
}, 0);
</script>
Both id based lookups and index based lookups take constant (i.e. O(1)
) time. Hope that helps.
I have a structure like this in an app. The API specified would make it difficult to create a structure like you want. Here are some things I noticed: DataStructure
is a singleton, addChild
doesn't allow you to add a node with children, and indexes are numbers. How about the following?
Members:
Methods:
Members:
Methods:
Methods:
Nothing here is immutable necessarily. You could however, via use of a new factory method and make more of the above methods private always force immutability of the tree. This may or may not be desirable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With