123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- const { Node, Link, Graph } = require("./graph");
- class TreeNode extends Node {
- constructor(id){
- super(id);
- this.depth = null;
- }
- }
- class Tree extends Graph {
- constructor(){
- super();
- this.root = null;
- this.levels = [];
- }
- /*addLink(link) {
- console.log("You cannot add Link because its deprecated ...Use Insert");
- return;
- }
- addNode(node){
- console.log("You cannot add Node because its deprecated ...Use Insert");
- return;
- }*/
- changeParent(node, parent) {
- let link = this.links[node.id].in.values().next().value;
- let oldparent = link.from;
- this.links[oldparent.id].out.delete(link);
- link.from = parent;
- this.links[parent.id].out.add(link);
- this.updateLevels(parent);
- }
- updateLevels(node) {
- let outSet = this.links[node.id].out;
- for(let link of outSet) {
- let child = this.getNode(link.to);
- if(child.depth !== node.depth + 1) {
- if(child.depth){
- this.levels[child.depth].delete(child.id);
- }
-
- child.depth = node.depth + 1;
- if(!this.levels[child.depth]){
- this.levels[child.depth] = new Set();
- }
- this.levels[child.depth].add(child.id);
- this.updateLevels(child);
- }
- }
- }
- insert(node,parentNode){
- if(this.nodes[node.id]){
- throw new Error("Node already Exists")
- }
- if(parentNode === null || parentNode === undefined) {
- super.addNode(node);
- this.root = node;
- this.root.depth = 0;
- this.levels = [new Set([this.root.id])];
- return;
- }
- if(!this.nodes[parentNode.id]){
- throw new Error("Parent Node does not Exist....Insert First ")
- }
- //console.log(node, parentNode);
- let link = new Link(parentNode.id,node.id);
- super.addNode(node);
- super.addLink(link);
- this.updateLevels(parentNode);
- }
- print() {
- console.log("§§§§§§§ Tree Structure §§§§§§§§§§");
- this.levels.forEach((level, index) => {
- console.log("Level ", index);
- level.forEach( id => console.log(` ${id} `));
- });
- console.log("§§§§§§§ Tree Structure End §§§§§§§§§§");
- }
- remove(node,propagation = true){
- propagation ? this.cleanup(node) : null;
- this.levels[node.depth].delete(node.id);
- if(this.levels[node.depth].size === 0) {
- this.levels.length = node.depth;
- }
- super.removeNode(node);
- }
- cleanup(parent) {
- let children = this.getChildren(parent);
- children.forEach(child => {
- this.remove(child);
- });
- }
-
- getParent(node) {
- return [...this.links[node.id].in].map(link => link.from)[0];
- }
- getChildren(node) {
- return [...this.links[node.id].out].map(link => this.getNode(link.to));
- }
- getLevel(depth) {
- return this.levels[depth];
- }
- replaceNode(oldNode,newNode){
- if(!this.nodes[oldNode.id]){
- throw new Error("The Node you are trying to replace doesnt exist in the current Tree")
- }
- newNode.depth = oldNode.depth
- let OldLinks = this.getLinks(oldNode.id);
- let OldFromNode;
- let OldToNodes = [];
- let OldDepth = oldNode.depth;
- let levels = this.levels;
- for(let m of OldLinks.in){
- OldFromNode = m.from
- }
- for(let k of OldLinks.out){
- OldToNodes.push(k.to)
- }
- this.remove(oldNode,false);
-
- //If the tree contains only the root this code will run
- if(this.levels.length === 0){
- this.levels = [new Set([newNode.id])]
- super.addNode(newNode);
- this.root = newNode;
- return true;;
-
- }
- //THIS PROCESS
- this.levels[OldDepth].add(newNode.id);
- super.addNode(newNode);
- if(OldFromNode){
- super.linkNodes(OldFromNode,newNode.id);
- }
- OldToNodes.map((node) => {
-
- super.linkNodes(newNode.id,node)
- })
-
- if(oldNode === this.root){
- console.log("never")
- this.root = newNode
- }
- }
- export() {
- let data = super.export();
- let levels = this.levels.map(level => Array.from(level));
- return {
- ...data,
- levels,
- rootId: this.root.id
- };
- }
- import(data, nodeType = TreeNode, parentNode) {
- let { levels, rootId, ...rest } = data;
- super.import(data, nodeType);
- if(!parentNode) {
- this.root = super.getNode(rootId);
- this.levels = levels.map(setArray => new Set(setArray));
- } else {
- this.linkNodes(parentNode, rootId);
- this.updateLevels(parentNode);
- }
- }
- }
- //console.log("SSSSSSSSSSSSSSSS")
- //console.log(A)
- //var B = new TreeNode('B');
- //var C = new TreeNode('C');
- //var D = new TreeNode('D');
- //var E = new TreeNode('E');
- //var F = new TreeNode("F");
- //console.log(tree.root)
- //console.log(tree)
- // tree.insert(B,A)
- // tree.insert(D,B)
- // tree.insert(E,D)
- // tree.insert(F,D)
- // tree.print();
- // tree.remove(D)
- // tree.print();
- module.exports = { Tree, TreeNode };
|