2010-02-02 10 views
5

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

+6

Eh bien, récursivement. J'espère que tu n'es pas mon élève. –

+2

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

+1

http://forums.devshed.com/software-design-43/finding-binary-tree-from-inorder-and-preorder-traversals-151147.html – Heinzi

Répondre

4

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:
Laissez p_1, p_2...p_n être le traversal postorder et laissez i_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 est p_n. Trouver cet élément dans la traversée de l'ordre, par exemple i_1, i_2...p_ni_k+1...i_n. A partir de la traversée inorder, on trouve tous les éléments dans le sous-arbre gauche, c'est-à-dire i_1, i_2...i_k-1 et dans le sous-arbre de droite, c'est-à-dire i_k+1...i_n respectivement. Supprimer l'élément p_n (et l'élément i_k==p_n). Trouver l'élément p_j à p_1 extrême droite, p_2...p_j...p_n-1p_j est un élément i_1, i_2 ... i_k-1. C'est la racine du sous-arbre gauche de l'arbre d'origine. de Split p_1, p_2...p_j et p_j+1 ... p_n-1 et i_1, i_2...i_k-1 et i_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!

+0

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

1

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é.