2017-10-20 40 views
0

Ma structure de données ressemblera à ceci:JavaScript - Comment puis-je retourner la branche d'un arbre dans une recherche de noeud?

var tree = [ 
    { 
     id: 1, 
     children: [] 
    }, { 
     id: 2, 
     children: [ 
      { 
       id: 3, 
       children: [] 
      } 
     ] 
    } 
]; 

Il peut y avoir un certain nombre de nœuds ou d'enfants sur une branche.

Mon but est de commencer par le nœud supérieur (racine), de rechercher un nœud donné et de retourner la branche sur laquelle il se trouve.

Ainsi, dans l'exemple de Plunker: https://plnkr.co/edit/PyR3H7mM0vrFyno1l7R5?p=catalogue

Je veux rechercher l'identifiant de noeud # 31, de sorte que l'algorithme retourne le tableau (branche) que 31 est une partie.

J'ai démarré l'algorithme mais si je le fais de façon récursive, je ne sais pas comment revenir en arrière.

function traverse(branch) { 

    for (var i = 0; i < branch.length; i++) { 
    if (branch[i].id == node.id) { 
     return branch; 
    } 
    } 

    for (var j = 0; j < branch.length; j++) { 
    if (branch[j].children.length > 0) { 
     return traverse(branch[j].children); 
    } 
    } 

} 

console.log(traverse(tree)); 

Par exemple, si je regarde vers le bas au dernier nœud enfant sans trouver un match alors je dois revenir en arrière à la branche mère d'essayer la prochaine série d'options.

Comment puis-je modifier mon algorithme pour revenir en arrière?

+0

Que voulez-vous revenir si un match ne se trouve pas? Vous ne devez renvoyer le résultat de l'appel récursif que s'il a trouvé quelque chose. – 4castle

+0

Dans ma situation, un match sera toujours trouvé parce que je vais faire en sorte que l'utilisateur clique sur l'un d'entre eux pour démarrer le processus de recherche. – user1261710

+0

Bien sûr, mais si vous voulez que votre code soit récursif, vous devez vous attendre à ce que toutes les branches de votre arbre ne contiennent pas de correspondance, donc vous devez retourner quelque chose dans ces cas-là. – 4castle

Répondre

1

Votre algorithme est très proche, il vous suffit d'ajouter une déclaration if afin qu'elle ne retourne que le résultat récurrent de traverse si une correspondance a été trouvée:

function traverse(branch) { 

    for (var i = 0; i < branch.length; i++) { 
    if (branch[i].id == node.id) { 
     return branch; 
    } 
    } 

    for (var j = 0; j < branch.length; j++) { 
    var result = traverse(branch[j].children); 
    if (result !== undefined) { 
     return result; 
    } 
    } 

    return undefined; // no match found 

} 

console.log(traverse(tree)); 
+0

Comment puis-je modifier l'algorithme afin qu'il trouve plusieurs correspondances au lieu d'une seule? – user1261710

+0

Au lieu de 'return'ing dans les boucles, vous devrez' pousser 'dans un tableau de 'results', puis retourner' 'results'' la fin. – 4castle

1

Vous pouvez utiliser une variable temporaire pour le résultat des enfants et quitter la boucle si la valeur est véridique.

function traverse(branch) { 
    var result; 
    for (var i = 0; i < branch.length; i++) { 
     if (branch[i].id === node.id) { 
      return branch; 
     } 
     if (branch[j].children.length > 0) { 
      result = traverse(branch[j].children); 
      if (result) { 
       return result; 
      } 
     } 
    } 
} 
0

Cela a fait l'affaire de retourner la branche plutôt que le nœud lui-même:

function traverse(branch) { 

     for (var i = 0; i < branch.length; i++) { 
      if (branch[i].id == node.id) { 
       return branch[i].children; 
      } 
     } 

     for (var j = 0; j < branch.length; j++) { 
      var result = traverse(branch[j].children); 
      if (result !== null) { 
       return result; 
      } 
     } 

     return null; // no match found 
    }