74

I have and object literal that is essentially a tree that does not have a fixed number of levels. How can I go about searching the tree for a particualy node and then return that node when found in an effcient manner in javascript?

Essentially I have a tree like this and would like to find the node with the title 'randomNode_1'

var data = [
{
title: 'topNode',
 children: [
   {
       title: 'node1',
       children: [
       {
           title: 'randomNode_1'
       },
       {   
           title: 'node2',
           children: [
           {
               title: 'randomNode_2',
               children:[
               {   
                   title: 'node2',
                   children: [
                   {
                       title: 'randomNode_3',
                   }]
               }
               ]
           }]
       }]
   }
  ]
 }];
Dave
  • 3,812
  • 5
  • 31
  • 39
  • 2
    did you tried recursion? – Shoaib Shaikh Feb 03 '12 at 18:25
  • 73
    @ShoaibShaikh: To understand recursion one must first understand recursion. – gen_Eric Feb 03 '12 at 18:30
  • 1
    Does your data structure really look like that? You're storing your child nodes in an array, but they're wrapped in a single object `{}`. You've specified two `title` attributes and two `children`, for example, as the children of "topNode". – voithos Feb 03 '12 at 18:33
  • Lol, that's a good joke @Rocket Hazmat (https://stackoverflow.com/users/206403/rocket-hazmat), just posted a graphic (https://pbs.twimg.com/media/DhnUDIRWsAoYBXo.jpg) of it here on Twitter. – Lapys Jul 08 '18 at 21:52

19 Answers19

109

Basing this answer off of @Ravindra's answer, but with true recursion.

function searchTree(element, matchingTitle){
     if(element.title == matchingTitle){
          return element;
     }else if (element.children != null){
          var i;
          var result = null;
          for(i=0; result == null && i < element.children.length; i++){
               result = searchTree(element.children[i], matchingTitle);
          }
          return result;
     }
     return null;
}

Then you could call it:

var element = data[0];
var result = searchTree(element, 'randomNode_1');
tanman
  • 1,379
  • 1
  • 10
  • 19
driangle
  • 11,601
  • 5
  • 47
  • 54
  • can i note the iteration path? – Sunil Garg Jul 09 '19 at 09:41
  • 1
    There is a way to modify this code so it pushes all the title keys in an array, for example titles = ["topNode", "node1", "randomNode_1", "node2", "randomNode2", "node2", "randomNode3" ] – Eduardo Alvarez Aug 23 '19 at 19:30
  • Sure, if result is returned as non-null, then the parent node must be on the path, so push the current node onto a result path array which can be added as a parameter to the function or exposed in an outer scope. – ggorlen Jul 05 '21 at 19:19
41

Here's an iterative solution:

var stack = [], node, ii;
stack.push(root);

while (stack.length > 0) {
    node = stack.pop();
    if (node.title == 'randomNode_1') {
        // Found it!
        return node;
    } else if (node.children && node.children.length) {
        for (ii = 0; ii < node.children.length; ii += 1) {
            stack.push(node.children[ii]);
        }
    }
}

// Didn't find it. Return null.
return null;
FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91
  • 13
    This should be an accepted answer, other recursive answers are prone to stackoverflow, especially in javascript – Yerken May 06 '16 at 07:45
  • Nice and clean! Can be shortened a bit more with the new es6 syntax. – Adrian Moisa Dec 06 '17 at 15:12
  • This will return the last node if no match was found – Yoav Kadosh Mar 21 '18 at 20:22
  • In fact, there isn't nothing being returned by this code. – Erick Petrucelli May 29 '18 at 19:17
  • 2
    I think when I wrote this many moons ago, my thought process was that you'd do something with the node in this method, rather than returning it. But who can tell? Past Me was capricious and prone to error. Totally not like Current Me at all ;) But I changed the code to return something now. Either way, the fundamental bones of an iterative solution are there. – FishBasketGordo Aug 28 '18 at 14:48
  • How would I get the path to the node as array? – Sam Aug 06 '21 at 13:12
31

Here's an iterative function using the Stack approach, inspired by FishBasketGordo's answer but taking advantage of some ES2015 syntax to shorten things.

Since this question has already been viewed a lot of times, I've decided to update my answer to also provide a function with arguments that makes it more flexible:

function search (tree, value, key = 'id', reverse = false) {
  const stack = [ tree[0] ]
  while (stack.length) {
    const node = stack[reverse ? 'pop' : 'shift']()
    if (node[key] === value) return node
    node.children && stack.push(...node.children)
  }
  return null
}

This way, it's now possible to pass the data tree itself, the desired value to search and also the property key which can have the desired value:

search(data, 'randomNode_2', 'title')

Finally, my original answer used Array.pop which lead to matching the last item in case of multiple matches. In fact, something that could be really confusing. Inspired by Superole comment, I've made it use Array.shift now, so the first in first out behavior is the default.

If you really want the old last in first out behavior, I've provided an additional arg reverse:

search(data, 'randomNode_2', 'title', true)
Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
  • 1
    can i note the tree iteration path? – Sunil Garg Jul 09 '19 at 09:43
  • Put the result of `stack.pop() || null` in a variable, so you can `console.log` it before returning. – Erick Petrucelli Jul 09 '19 at 13:47
  • such a clean answer. however when the node is nested it fails with a Cannot read property 'Symbol(Symbol.iterator)' of stack.push error – Jeff Voss Nov 09 '19 at 00:07
  • 1
    Thanks @iamwhitebox, you're right. We need to check if there's `node.children` before trying to use `...` on it. Or even a simple short-circuit `&&` conditional as I chose in the updated answer. – Erick Petrucelli Nov 09 '19 at 16:21
  • the only way you reach the last return statement is when the stack.length === 0, which in turn means that `stack.pop()` will always return undefined. -So why not just return null? – Superole Apr 03 '20 at 12:16
  • ...also if you use shift() and unshift() instead of pop() and push(), you will search from left to right (which feels more natural IMO), and find the first match instead of the last in case of multiple matches – Superole Apr 03 '20 at 12:32
  • @Superole, thanks by your thoughts. I've just updated the answer considering it and I believe it's really better now. – Erick Petrucelli Apr 04 '20 at 16:51
  • 1
    In addition to the tree searching, TIL conditional methods are a thing. Mind blown. – Chase Jun 02 '20 at 19:40
  • Keep in mind `shift` is linear while `pop` is O(1), so this has a hidden performance penalty if you do pass in `reverse = true`. If performance matters, use a queue. `.push(...node.children)` can blow the stack if there are too many arguments. – ggorlen Jul 05 '21 at 19:22
  • @ggorlen could you please provide the source of your performance considerations? First of all, ECMAScript specification doesn't specifies any bounding complexity. But even if considering the common algorithm implementations, it seems that `pop` is **O(1)** while `shift` is **O(N)**, as found in https://stackoverflow.com/a/22615787/424498. This is also what MythBusters JS states [here](https://mythbusters.js.org/#/array/pop-or-shift). – Erick Petrucelli Jul 10 '21 at 17:17
  • @ErickPetrucelli Your links support my assertion; linear is the same as O(n). These array operations are core algorithm knowledge and aren't specific to JS so pick any algorithm text book or reference as a source if you need one and feel free to ping me if you find a counterexample. The fact that shift _can_ be implemented as O(1) in certain circumstances is interesting, but practically I would assume O(n). – ggorlen Jul 10 '21 at 17:31
  • @ggorlen, yes linear is the same as **O(n)**. Yes, `shift` is probably **O(n)**. So how could that support your performance assertions? No, **O(n)** is not faster than **O(1)**, this is a core algorithm performance knowledge. So no, `shift` is not faster than `pop` (considering the usual implementation and usual circumstances). So how could your allegation that passing `reverse = true` could have a hidden performance penalty? It's exactly the inverse case! And because of that inverted affirmation I questioned your affirmation since the beginning. – Erick Petrucelli Jul 12 '21 at 20:35
  • My mistake -- I meant `reverse === false`, the default value, has the performance penalty. The variable name `stack` is pretty confusing because it's really an (inefficiently implemented) queue by default and a stack when you take extra pains to pass the third argument as `true`. I didn't mean for this to be a long thread, just mentioning this before anyone gets bitten by accidental quadratic behavior. – ggorlen Jul 12 '21 at 21:01
  • Yes, now that we clarified your allegation, good point. Just to clarify here that I agreed with @Superole more than a year ago that a "left to right" search would be more "natural" to most developer, so because of that the `reverse = false` is the default behavior. But your consideration, @ggorlen, is also an important addendum to those doing searches on potentially larger trees where the **O(n)** performance can be a trouble. Thanks. – Erick Petrucelli Jul 13 '21 at 22:15
7

My answer is inspired from FishBasketGordo's iterativ answer. It's a little bit more complex but also much more flexible and you can have more than just one root node.

/**searchs through all arrays of the tree if the for a value from a property
 * @param aTree : the tree array
 * @param fCompair : This function will receive each node. It's upon you to define which 
                     condition is necessary for the match. It must return true if the condition is matched. Example:
                        function(oNode){ if(oNode["Name"] === "AA") return true; }
 * @param bGreedy? : us true to do not stop after the first match, default is false
 * @return an array with references to the nodes for which fCompair was true; In case no node was found an empty array
 *         will be returned
*/
var _searchTree = function(aTree, fCompair, bGreedy){
    var aInnerTree = []; // will contain the inner children
    var oNode; // always the current node
    var aReturnNodes = []; // the nodes array which will returned

    // 1. loop through all root nodes so we don't touch the tree structure
    for(keysTree in aTree) {
        aInnerTree.push(aTree[keysTree]);
    }
    while(aInnerTree.length > 0) {
        oNode = aInnerTree.pop();
        // check current node
        if( fCompair(oNode) ){
            aReturnNodes.push(oNode);
            if(!bGreedy){
                return aReturnNodes;
            }
        } else { // if (node.children && node.children.length) {
            // find other objects, 1. check all properties of the node if they are arrays
            for(keysNode in oNode){
                // true if the property is an array
                if(oNode[keysNode] instanceof Array){
                    // 2. push all array object to aInnerTree to search in those later
                    for (var i = 0; i < oNode[keysNode].length; i++) {
                        aInnerTree.push(oNode[keysNode][i]);
                    }
                }
            }
        }
    }
    return aReturnNodes; // someone was greedy
}

Finally you can use the function like this:

var foundNodes = _searchTree(data, function(oNode){ if(oNode["title"] === "randomNode_3") return true; }, false);
console.log("Node with title found: ");
console.log(foundNodes[0]);

And if you want to find all nodes with this title you can simply switch the bGreedy parameter:

var foundNodes = _searchTree(data, function(oNode){ if(oNode["title"] === "randomNode_3") return true; }, true);
console.log("NodeS with title found: ");
console.log(foundNodes);
Tim Malich
  • 1,301
  • 14
  • 22
5

FIND A NODE IN A TREE :

let say we have a tree like

let tree = [{
  id: 1,
  name: 'parent',
  children: [
    {
      id: 2,
      name: 'child_1'
    },
    {
      id: 3,
      name: 'child_2',
      children: [
        {
          id: '4',
          name: 'child_2_1',
          children: []
        },
        {
          id: '5',
          name: 'child_2_2',
          children: []
        }
      ]
    }
  ]
}];


function findNodeById(tree, id) {

   let result = null
   if (tree.id === id) {
        return tree;
   }

   if (Array.isArray(tree.children) && tree.children.length > 0) {
      tree.children.some((node) => {
        result = findNodeById(node, id);
        return result;
      });
   }
   return result;}
subramanian
  • 1,125
  • 1
  • 12
  • 12
4

You have to use recursion.

var currChild = data[0];
function searchTree(currChild, searchString){
     if(currChild.title == searchString){
          return currChild;
     }else if (currChild.children != null){
          for(i=0; i < currChild.children.length; i ++){
               if (currChild.children[i].title ==searchString){
                    return currChild.children[i];
               }else{
                    searchTree(currChild.children[i], searchString);
               }
          }
          return null;
     }
     return null;
}
Ravindra Gullapalli
  • 9,049
  • 3
  • 48
  • 70
3

ES6+:

const deepSearch = (data, value, key = 'title', sub = 'children', tempObj = {}) => {
    if (value && data) {
        data.find((node) => {
            if (node[key] == value) {
                tempObj.found = node;
                return node;
            }
            return deepSearch(node[sub], value, key, sub, tempObj);
        });
        if (tempObj.found) {
            return tempObj.found;
        }
    }
    return false;
};

const result = deepSearch(data, 'randomNode_1', 'title', 'children');
HANNAN Std
  • 369
  • 5
  • 7
2

This function is universal and does search recursively. It does not matter, if input tree is object(single root), or array of objects (many root objects). You can configure prop name that holds children array in tree objects.

// Searches items tree for object with specified prop with value
// 
// @param {object} tree nodes tree with children items in nodesProp[] table, with one (object) or many (array of objects) roots
// @param {string} propNodes name of prop that holds child nodes array
// @param {string} prop name of searched node's prop
// @param {mixed} value value of searched node's  prop
// @returns {object/null} returns first object that match supplied arguments (prop: value) or null if no matching object was found

function searchTree(tree, nodesProp, prop, value) {
  var i, f = null; // iterator, found node
  if (Array.isArray(tree)) { // if entry object is array objects, check each object
    for (i = 0; i < tree.length; i++) {
      f = searchTree(tree[i], nodesProp, prop, value);
      if (f) { // if found matching object, return it.
        return f;
      }
    }
  } else if (typeof tree === 'object') { // standard tree node (one root)
    if (tree[prop] !== undefined && tree[prop] === value) {
      return tree; // found matching node
    }
  }
  if (tree[nodesProp] !== undefined && tree[nodesProp].length > 0) { // if this is not maching node, search nodes, children (if prop exist and it is not empty)
    return searchTree(tree[nodesProp], nodesProp, prop, value);
  } else {
    return null; // node does not match and it neither have children
  }
}

I tested it localy and it works ok, but it somehow won't run on jsfiddle or jsbin...(recurency issues on those sites ??)

run code :

    var data = [{
      title: 'topNode',
      children: [{
        title: 'node1',
        children: [{
          title: 'randomNode_1'
        }, {
          title: 'node2',
          children: [{
            title: 'randomNode_2',
            children: [{
              title: 'node2',
              children: [{
                title: 'randomNode_3',
              }]
            }]
          }]
        }]
      }]
    }];

    var r = searchTree(data, 'children', 'title', 'randomNode_1');
    //var r = searchTree(data, 'children', 'title', 'node2');  // check it too
    console.log(r);

It works in http://www.pythontutor.com/live.html#mode=edit (paste the code)

Tom
  • 21
  • 3
2

no BS version:

const find = (root, title) => 
  root.title === title ?
    root :
    root.children?.reduce((result, n) => result || find(n, title), undefined)

Usage:

const data = {
  title: "root",
  children: [
    { title: "ch1" },
    { title: "ch2", children: [{ title: "ch21" }] }
  ]
}

find(data, 'ch21') // returns { title: 'ch21' }
oluckyman
  • 3,566
  • 3
  • 28
  • 35
  • I would to like use this functional approach but `find` always returns `undefined` regardless of the title searched. Did it work for you? – user2309803 Feb 02 '23 at 11:03
  • yes, it works for me. Check your data format. it should be nested structure with objects `{ title, children: [] }` – oluckyman Feb 06 '23 at 09:35
  • I tried `> find(data, {title: 'randomNode_3'})` and `> find(data, {title: 'randomNode_3', children: []})` but they both return `undefined`. Could you please post your example which works? – user2309803 Feb 24 '23 at 08:40
  • @user2309803 updated the answer with example – oluckyman Apr 29 '23 at 12:13
1

here is a more complex option - it finds the first item in a tree-like node with providing (node, nodeChildrenKey, key/value pairs & optional additional key/value pairs)

const findInTree = (node, childrenKey, key, value,  additionalKey?, additionalValue?) => {
  let found = null;
  if (additionalKey && additionalValue) {
    found = node[childrenKey].find(x => x[key] === value && x[additionalKey] === additionalValue);
  } else {
    found = node[childrenKey].find(x => x[key] === value);
  }
  if (typeof(found) === 'undefined') {
    for (const item of node[childrenKey]) {
      if (typeof(found) === 'undefined' && item[childrenKey] && item[childrenKey].length > 0) {
        found = findInTree(item, childrenKey, key, value, additionalKey, additionalValue);
      }
    }
  }
  return found;
};

export { findInTree };

Hope it helps someone.

Ugran
  • 25
  • 7
1

In 2022 use TypeScript and ES5

Just use basic recreation and built-in array method to loop over the array. Don't use Array.find() because this it will return the wrong node. Use Array.some() instead which allow you to break the loop.

 interface iTree {
     id: string;
     children?: iTree[];
 }

function findTreeNode(tree: iTree, id: string) {
    let result: iTree | null = null;

    if (tree.id === id) {
        result = tree;
    } else if (tree.children) {
        tree.children.some((node) => {
            result = findTreeNode(node, id);
            return result; // break loop
        });
    }

    return result;
}
Gil Epshtain
  • 8,670
  • 7
  • 63
  • 89
1

This is basic recursion problem.

window.parser = function(searchParam, data) {
  if(data.title != searchParam) {
    returnData = window.parser(searchParam, children)
  } else {
     returnData = data;
  }

  return returnData;
}
Valerio Bozz
  • 1,176
  • 16
  • 32
thenetimp
  • 9,487
  • 5
  • 29
  • 42
0

A flexible recursive solution that will work for any tree

// predicate: (item) => boolean
// getChildren: (item) => treeNode[]
searchTree(predicate, getChildren, treeNode) {
        function search(treeNode) {
            if (!treeNode) {
                return undefined;
            }

            for (let treeItem of treeNode) {
                if (predicate(treeItem)) {
                    return treeItem;
                }

                const foundItem = search(getChildren(treeItem));

                if (foundItem) {
                    return foundItem;
                }
            }
        }

        return search(treeNode);
    }
Eyal Ofri
  • 680
  • 10
  • 16
0

find all parents of the element in the tree

let objects = [{
      id: 'A',
      name: 'ObjA',
      children: [
        {
          id: 'A1',
          name: 'ObjA1'
        },
        {
          id: 'A2',
          name: 'objA2',
          children: [
            {
              id: 'A2-1',
              name: 'objA2-1'
            },
            {
              id: 'A2-2',
              name: 'objA2-2'
            }
          ]
        }
      ]
    },
    {
      id: 'B',
      name: 'ObjB',
      children: [
        {
          id: 'B1',
          name: 'ObjB1'
        }
      ]
    }
    ];

let docs = [
  {

    object: {
      id: 'A',
      name: 'docA'
    },
    typedoc: {
      id: 'TD1',
      name: 'Typde Doc1'
    }
  },
  {

    object: {
      id: 'A',
      name: 'docA'
    },
    typedoc: {
      id: 'TD2',
      name: 'Typde Doc2'
    }
  },
  {

    object: {
      id: 'A1',
      name: 'docA1'
    },
    typedoc: {
      id: 'TDx1',
      name: 'Typde Doc x1'
    }
  },
  {

    object: {
      id: 'A1',
      name: 'docA1'
    },
    typedoc: {
      id: 'TDx2',
      name: 'Typde Doc x1'
    }
  },
  {

    object: {
      id: 'A2',
      name: 'docA2'
    },
    typedoc: {
      id: 'TDx2',
      name: 'Type de Doc x2'
    }
  },
  {

    object: {
      id: 'A2-1',
      name: 'docA2-1'
    },
    typedoc: {
      id: 'TDx2-1',
      name: 'Type de Docx2-1'
    },
  },
  {

    object: {
      id: 'A2-2',
      name: 'docA2-2'
    },
    typedoc: {
      id: 'TDx2-2',
      name: 'Type de Docx2-2'
    },
  },
  {

    object: {
      id: 'B',
      name: 'docB'
    },
    typedoc: {
      id: 'TD1',
      name: 'Typde Doc1'
    }
  },
  {

    object: {
      id: 'B1',
      name: 'docB1'
    },
    typedoc: {
      id: 'TDx1',
      name: 'Typde Doc x1'
    }

  }
];



function buildAllParents(doc, objects) {
    for (let o = 0; o < objects.length; o++) {
      let allParents = [];
      let getAllParents = (o, eleFinded) => {
        if (o.id === doc.object.id) {
          doc.allParents = allParents;
          eleFinded = true;
          return { doc, eleFinded };
        }
        if (o.children) {
          allParents.push(o.id);
          for (let c = 0; c < o.children.length; c++) {
            let { eleFinded, doc } = getAllParents(o.children[c], eleFinded);
            if (eleFinded) {
              return { eleFinded, doc };
            } else {
              continue;
            }
          }

        }
        return { eleFinded };
      };
      if (objects[o].id === doc.object.id) {
        doc.allParents = [objects[o].id];
        return doc;
      } else if (objects[o].children) {
        allParents.push(objects[o].id);
        for (let c = 0; c < objects[o].children.length; c++) {
          let eleFinded = null;`enter code here`
          let res = getAllParents(objects[o].children[c], eleFinded);
          if (res.eleFinded) {
            return res.doc;
          } else {
            continue;
          }
        }
      }

    }
  }

docs = docs.map(d => buildAllParents(d, objects`enter code here`))
Yaser Darzi
  • 1,480
  • 12
  • 24
0

This is an iterative breadth first search. It returns the first node that contains a child of a given name (nodeName) and a given value (nodeValue).

getParentNode(nodeName, nodeValue, rootNode) {
    const queue= [ rootNode ]
    while (queue.length) {
        const node = queue.shift()
        if (node[nodeName] === nodeValue) {
            return node
        } else if (node instanceof Object) {
            const children = Object.values(node)
            if (children.length) {
                queue.push(...children)
            }
        }
    }
    return null
}

It would be used like this to solve the original question:

getParentNode('title', 'randomNode_1', data[0])
Fede Garcia
  • 677
  • 11
  • 18
0

Enhancement of the code based on "Erick Petrucelli"

  1. Remove the 'reverse' option
  2. Add multi-root support
  3. Add an option to control the visibility of 'children'
  4. Typescript ready
  5. Unit test ready
function searchTree(
  tree: Record<string, any>[],
  value: unknown,
  key = 'value',
  withChildren = false,
) {
  let result = null;
  if (!Array.isArray(tree)) return result;

  for (let index = 0; index < tree.length; index += 1) {
    const stack = [tree[index]];
    while (stack.length) {
      const node = stack.shift()!;
      if (node[key] === value) {
        result = node;
        break;
      }
      if (node.children) {
        stack.push(...node.children);
      }
    }
    if (result) break;
  }
  if (withChildren !== true) {
    delete result?.children;
  }

  return result;
}

And the tests can be found at: https://gist.github.com/aspirantzhang/a369aba7f84f26d57818ddef7d108682

0

Wrote another one based on my needs

  1. condition is injected.
  2. path of found branch is available
  3. current path could be used in condition statement
  4. could be used to map the tree items to another object
// if predicate returns true, the search is stopped
function traverse2(tree, predicate, path = "") {
  if (predicate(tree, path)) return true;
  for (const branch of tree.children ?? [])
    if (traverse(branch, predicate, `${path ? path + "/" : ""}${branch.name}`))
      return true;
}

example

let tree = {
  name: "schools",
  children: [
    {
      name: "farzanegan",
      children: [
        {
          name: "classes",
          children: [
            { name: "level1", children: [{ name: "A" }, { name: "B" }] },
            { name: "level2", children: [{ name: "C" }, { name: "D" }] },
          ],
        },
      ],
    },
    { name: "dastgheib", children: [{ name: "E" }, { name: "F" }] },
  ],
};

traverse(tree, (branch, path) => {
  console.log("searching ", path);
  if (branch.name === "C") {
    console.log("found ", branch);
    return true;
  }
});

output

searching  
searching  farzanegan
searching  farzanegan/classes
searching  farzanegan/classes/level1
searching  farzanegan/classes/level1/A
searching  farzanegan/classes/level1/B
searching  farzanegan/classes/level2
searching  farzanegan/classes/level2/C
found  { name: 'C' }
Ali80
  • 6,333
  • 2
  • 43
  • 33
0
const flattenTree = (data: any) => {
  return _.reduce(
    data,
    (acc: any, item: any) => {
      acc.push(item);
      if (item.children) {
        acc = acc.concat(flattenTree(item.children));
        delete item.children;
      }
     return acc;
    },
    []
    );
   };

An Approach to convert the nested tree into an object with depth 0. We can convert the object in an object like this and can perform search more easily.

saumyajain125
  • 93
  • 1
  • 4
-1

The following is working at my end:

function searchTree(data, value) {
if(data.title == value) {
    return data;
}
if(data.children && data.children.length > 0) {
    for(var i=0; i < data.children.length; i++) {
        var node = traverseChildren(data.children[i], value);
        if(node != null) {
            return node;
        }
    }
}
return null;

}

Amitabha Roy
  • 769
  • 5
  • 8