Comment puis-je construire un arbre étant donné sa traversée inorder et précommande? Je suis juste à la recherche d'un algorithme efficace.Construire un arbre
Répondre
Une copie flagrante et pâte de Sun's (Oracle now, I guess...) forum:
Question:
Quelqu'un peut-il me aider sur la façon de construire l'arbre binaire de envue et Postorder traversals, je veux juste savoir l'algorithme de sorte que je peux l'appliquer.Réponse:
Laissezp_1
,p_2
...
p_n
être le traversal postorder et laissezi_1
,i_2
...
i_n
être le parcours infixe. A partir de la traversée du post-ordre, nous savons que la racine de l'arbre estp_n
. Trouver cet élément dans la traversée de l'ordre, par exemplei_1
,i_2
...
p_n
i_k+1
...
i_n
. A partir de la traversée inorder, on trouve tous les éléments dans le sous-arbre gauche, c'est-à-direi_1
,i_2
...
i_k-1
et dans le sous-arbre de droite, c'est-à-direi_k+1
...
i_n
respectivement. Supprimer l'élémentp_n
(et l'élémenti_k
==
p_n
). Trouver l'élémentp_j
àp_1
extrême droite,p_2
...
p_j
...
p_n-1
oùp_j
est un élémenti_1
,i_2
...i_k-1
. C'est la racine du sous-arbre gauche de l'arbre d'origine. de Splitp_1
,p_2
...
p_j
etp_j+1
...p_n-1
eti_1
,i_2
...
i_k-1
eti_k+1
...
i_n
. Vous avez maintenant deux sous-séquences représentant la traversée post-ordre et inorder des deux sous-arbres de l'arbre original .
Auteur: JosAH.
J'ai implémenté l'algorithme une fois en suivant les instructions de Jos, et cela a fonctionné parfaitement!
Il est trop long de trouver l'élément le plus à droite p_j dans p_1 ~ p_n-1 alors qu'il est aussi dans i_1 ~ i_k-1. Il prend l'heure O (n^2). En fait, après avoir supprimé p_n, et trouver sa position dans i_1 ~ i_n. Nous connaissons déjà la position de p_j. C'est parce que nous connaissons déjà le nombre de nœuds dans ses sous-arbres gauche et droit, ce qui pourrait être obtenu en comptant les éléments après p_n dans i_1 ~ i_n. Par ceci, nous pourrions facilement trouver l'endroit pour diviser p_1 ~ p_n-1 – ibread
Puisqu'il s'agit de devoirs, je ne vous donnerai pas de réponse complète, mais j'espère, assez pour vous aider à bouger. Imaginez que vous ayez une traversée de précommande de, disons this arborescence. La traversée vous donne 2-7-2-6-5-11-5 ... etc. Remarquez que le 5 est en fait le bon enfant de la racine.De toute évidence, vous ne pouvez pas le dire simplement en regardant les chiffres, donc soit vous serez informé de la structure de l'arbre, soit vous aurez besoin de stocker des données supplémentaires (c'est-à-dire, si un nœud est à gauche). enfant ou enfant droit, par exemple).
L'analyse de l'arborescence est simplement une fonction récursive qui prend en entrée la traversée de précommande (pensez à votre portée lorsque vous transmettez l'entrée). Comme je l'ai mentionné plus tôt, votre traversée pré-ordre devrait avoir des données supplémentaires attachées.
Efficacité:
considèrent combien de fois chaque nœud est visité lorsque vous construisez cet arbre, mais aussi envisager l'opération de lecture de l'entrée. Y at-il un moyen de réorganiser l'entrée plus rapidement que vous pouvez construire l'arbre? Quelle structure devrez-vous utiliser si vous avez besoin de manipuler les données.
Dans l'ordre: Vous aurez besoin de la même idée pour passer à travers, donc je ne vais pas le couvrir. Je suis sûr que quelqu'un d'autre le fera, si vous êtes désespéré.
Eh bien, récursivement. J'espère que tu n'es pas mon élève. –
Aurait besoin de clarification. Quel est le format des données d'entrée? L'arbre est-il équilibré? Que voulez-vous dire par efficace (Ordo (x), ou simplement "pas horriblement fou"). Quelle est la structure que vous voulez construire? Arborescence en tant qu'objets liés, ou arborescence en utilisant un tableau. – ron
http://forums.devshed.com/software-design-43/finding-binary-tree-from-inorder-and-preorder-traversals-151147.html – Heinzi