class Link { constructor(to, from) { this.from = from; this.to = to; } } class Node { constructor(id){ this.id = id; } } class Tree { constructor(NodeType){ this.root = new NodeType(-1); this.links = { [this.root.id]: this._emptyLink() }; } _emptyLink() { return { out: new Set(), in: null }; } updateLinkOut(node, link) { this.links[node.id].out.add(link); } updateLinkIn(node, link) { this.links[node.id].in = link; } insert(node, parentNode = this.root) { this.links[node.id] = this._emptyLink(); let newLink = new Link(node,parentNode); this.updateLinkIn(node, newLink); this.updateLinkOut(parentNode, newLink); } traverseTree(current) { if(!current) current = this.root; console.log(current.id); let set = this.links[current.id].out; return set.forEach((link, index) => { let next = link.to;// WOW return next && this.traverseTree(next); }); } bfs(current = this.root) { if(!current) current = this.root; var stack = [current] , node; while(stack.length > 0) { node = stack.shift(); let set = this.links[node.id].out; set.forEach((item) => stack.push(item.to)); // Do something console.log(node.id) } } removeLink(link) { let parentOut = this.links[link.from.id].out; parentOut.delete(link); this.links[link.to.id].in = null; } removeNode(node){ let link = this.links[node.id].in; this.removeLink(link); return node; } updateNode(node, newNode) { //update Links } updateLink(link, newLink) { // update Link } } var tree = new Tree(Node); var child1 = new Node(1); var child2 = new Node(2); tree.insert(child1); tree.insert(child2); tree.insert(new Node('L2-1-1'), child1); tree.insert(new Node('L2-1-2'), child1); tree.insert(new Node('L2-2-1'), child2); tree.traverseTree(); console.log("----- BFS ---- "); tree.bfs(); tree.removeNode(child1); console.log("----- BFS ---- Child1"); tree.bfs(child1);