L'arbre binaire n'est pas nécessairement un arbre de recherche binaire.
La structure peut être considérée comme -
struct node {
int data;
struct node *left;
struct node *right;
};
La solution maximale que j'ai pu trouver avec un ami était de l'ordre de -
Considérer cet arbre binaire :
Le parcours dans l'ordre donne - 8, 4, 9, 2, 5, 1, 6, 3, 7
Et la traversée post-ordre donne - 8, 9, 4, 5, 2, 6, 7, 3, 1
Ainsi, par exemple, si nous voulons trouver l'ancêtre commun des nœuds 8 et 5, nous dressons une liste de tous les nœuds situés entre 8 et 5 dans l'ordre de parcours de l'arbre, qui, dans ce cas, est [4, 9, 2]. Ensuite, nous vérifions quel nœud de cette liste apparaît en dernier dans le parcours post-ordre, qui est 2. Par conséquent, l'ancêtre commun de 8 et 5 est 2.
La complexité de cet algorithme est, je crois, de O(n) (O(n) pour les traversées dans l'ordre/post-ordre, le reste des étapes étant à nouveau de O(n) puisqu'il ne s'agit que de simples itérations dans des tableaux). Mais il y a de fortes chances que ce soit faux :-)
Mais il s'agit d'une approche très rudimentaire, et je ne suis pas sûr qu'elle ne fonctionne pas dans certains cas. Existe-t-il une autre solution (éventuellement plus optimale) à ce problème ?
6 votes
Par curiosité, quelle en est l'utilité pratique ?
19 votes
@David : La réponse aux requêtes LCA est très utile. LCA + arbre des suffixes = algorithmes puissants liés aux chaînes de caractères.
44 votes
Et lorsque j'ai posé une question similaire, elle a été rejetée avec des commentaires comme la question de l'entretien. Dualité du SO ? :(
0 votes
Je pense que votre code ne fonctionnera pas lorsque nous essaierons de trouver l'ACL pour n'importe quel parent et son enfant de droite. Par exemple, l'ACL pour 1 et 7 sera nul, mais selon votre code, il s'agira de 3.
5 votes
@Siddant +1 pour les détails donnés dans la question :)
0 votes
@LoveGupta Comment calculez-vous cela ? La liste des nœuds entre 1 et 7 dans la traversée dans l'ordre est [1, 6, 3, 7]. Parmi ces nœuds, le nœud 1 apparaît en dernier dans le parcours post-ordre. Il calcule donc que l'ACL des nœuds 1 et 7 est 1, ce qui est correct.
0 votes
Cette logique échouera si vous prenez les nœuds 9 et 7
0 votes
@sagivo pourquoi dites-vous cela ? En suivant la méthode décrite dans le billet, il faut regarder l'élément le plus à droite de {2,5,1,6,3} dans l'arbre post-ordre. Cet élément est 1, qui se trouve être l'ACL de 9 et 7.
1 votes
Là où il échoue, c'est lorsqu'il s'agit d'une paire comme 4 et 9 (ce qui, je pense, est ce à quoi @LoveGupta voulait en venir). Mais ce problème est facilement résolu. Il suffit de faire en sorte que la première étape (où l'on choisit des éléments dans l'arbre d'ordre) englobe tous les noeuds considérés (et pas seulement les noeuds entre les deux ). On obtient donc {4,9} dans l'arbre inorder et l'élément le plus à droite de ces 2 dans l'arbre postorder est 4, ce qui est ce que nous voulons.
0 votes
@neeraj2808 - Oui, vous avez raison, pour que ce code fonctionne dans tous les cas, nous devons inclure les éléments lors de la prise en compte d'un ensemble :)
5 votes
@DavidBrunelle Une application pratique du calcul de l'ACV : il s'agit d'un calcul essentiel lors du rendu des pages web, en particulier lors du calcul des feuilles de style en cascade (CSS) applicables à un élément DOM particulier.
1 votes
Votre solution est géniale ! Elle m'aide à comprendre les propriétés de la traversée inorder et postorder !