Je dois créer un algorithme récursif pour voir si un arbre binaire est un arbre de recherche binaire ainsi que compter le nombre de branches complètes (un nœud parent avec les nœuds enfants gauche et droit) avec une variable de comptage globale supposée. Il s'agit d'une affectation pour ma classe de structures de données.
Jusqu'à présent, j'ai
void BST(tree T) {
if (T == null) return
if ( T.left and T.right) {
if (T.left.data < T.data or T.right.data > T.data) {
count = count + 1
BST(T.left)
BST(T.right)
}
}
}
Mais je ne peux pas vraiment comprendre celui-ci. Je sais que cet algorithme ne résoudra pas le problème car le nombre sera nul si la seconde instruction if n'est pas vraie.
Quelqu'un pourrait-il m'aider sur celui-ci?
algorithms
recursion
trees
OghmaOsiris
la source
la source
<
défini sur les nœuds?true
oufalse
?Réponses:
Comme d'autres l'ont déjà indiqué dans les commentaires, vous avez vraiment deux fonctions non liées ici: tester si l'arborescence est une arborescence de recherche et compter les branches complètes. À moins que la mission ne l'exige spécifiquement, j'écrirais deux fonctions distinctes.
Voyons d'abord compter les branches complètes. Cela signifie compter les nœuds qui ont à la fois un enfant gauche et un enfant droit. Ensuite, vous devez incrémenter le compteur (
count = count + 1
) lorsque les deuxT.left
et neT.right
sont pas nuls (pasT.left.data
etT.right.data
: les données n'ont pas d'importance pour cette tâche).En outre, vous devez explorer le sous-arbre gauche même si le sous-arbre droit est vide, et vous devez explorer le sous-arbre droit même si le sous-arbre gauche est vide. Regardez donc où vous placez les appels récursifs.
Pour tester si l'arborescence est une arborescence de recherche, vous devez inspecter les valeurs des données. Vous avez déjà quelque chose de proche de la bonne comparaison; pas tout à fait juste. Écrivez quelques exemples d'arbres de formes variées (pas très gros, 2 à 5 nœuds) et exécutez votre algorithme dessus pour voir ce qui se passe.
Vous devez encore trouver un endroit où mettre le résultat du contrôle de validité. Encore une fois, regardez où vous placez les appels récursifs (si vous ne faites que cette partie, il existe plusieurs solutions, mais à ce stade, ne vous inquiétez pas si vous n'en voyez qu'une).
Enfin, une fois que vous avez réussi à écrire les deux fonctions séparément et que vous les avez testées sur quelques exemples, assemblez-les soigneusement (si la tâche l'exige).
la source
Dans des choses comme celle-ci, il est souvent plus facile de penser à l'envers, alors pensez d'abord à ce dont vous avez besoin. À partir de votre description, listons-les:
OK, c'est une liste assez courte, cela devrait être gérable. Commençons par une méthode vide et j'ajouterai une description de ce qui devrait se passer.
Maintenant validité. Comment vérifiez-vous la validité? Dans le chat, vous avez dit qu'un arbre est valide "si ... tous les enfants de gauche sont inférieurs au parent et les enfants de droite sont supérieurs au parent". Je suis sûr que vous vouliez également permettre l'égalité. Ce serait
t.left.value <= t.value <= t.right.value
.Mais que faire si l'un des enfants est porté disparu? D'après ce que vous avez dit, je pense que vous savez que le nœud est toujours valide s'il en manque un (ou les deux). Ajoutons ceci, restructurant légèrement:
OK, nous savons maintenant si ce nœud est valide. Comment vérifions-nous si l’arbre entier est valide? Ce n'est pas dans un tableau, donc nous ne pouvons / ne voulons probablement pas le boucler linéairement. Votre mission donne la réponse: récursivité. Mais comment accumuler une réponse en utilisant la récursivité? Nous avons accès à trois informations, si ce nœud est valide, et le résultat d'appels demandant si les nœuds gauche et droit sont valides. Évidemment, l'arbre n'est valide que si les trois sont vraies.
Si vous faites attention, cela nous dit même ce que notre fonction doit retourner.
Maintenant, comment intégrons-nous le comptage? Vous dites ce qui compte ("un nœud parent avec des nœuds enfants gauche et droit"), et cela ne devrait pas être difficile à traduire en code réel. Vérifiez si cette condition est remplie et incrémentez le compteur de manière appropriée. N'oubliez pas que cela doit être quelque part où il sera atteint chaque fois que cela sera vrai.
Et bien sûr, j'ai omis certains détails comme la condition d'arrêt de récursivité et vérifie la valeur null.
la source
Mes trois commentaires ci-dessus sont trois indices de problèmes avec votre code.
node1.value < node2.value
if
est vrai, êtes-vous sûr que c'est ce que vous vouliez faire? Par ailleurs, vous voudrez peut-être vérifier que cette instruction if fait ce que vous voulez.la source