la reconstruction d'un arbre à partir de sa précommande et postorder listes
Considérons une situation où vous avez deux listes de noeuds de qui vous savez est que l'on est une représentation d'une précommande de la traversée de quelques arbres, et de l'autre une représentation d'un postorder de la traversée de la même arborescence.
Je crois qu'il est possible de reconstituer exactement l'arbre à partir de ces deux listes, et je pense que j'ai un algorithme pour le faire, mais n'ont pas prouvé. Comme ce sera une partie d'un projet de maîtrise j'ai besoin d'être absolument certain qu'il est possible et correct (Mathématiquement prouvé). Toutefois, il ne sera pas le point central du projet, donc je me demandais si il y a une source là-bas (c'est à dire de papier ou d'un livre) je pourrais citer pour la preuve. (Peut-être dans TAOCP? quelqu'un sait la section, éventuellement?)
En bref, j'ai besoin avéré de l'algorithme dans un quotable ressource qui reconstitue un arbre à partir de son pré et post afin traversals.
Remarque: L'arbre en question ne sera probablement pas être binaire, ou d'équilibre, ou tout ce qui serait trop facile.
Note2: en Utilisant uniquement la précommande ou la postorder liste serait encore mieux, mais je ne pense pas que c'est possible.
Nota3: Un nœud peut avoir n'importe quel nombre d'enfants.
Note4: je ne se soucient de l'ordre des frères et sœurs. De gauche ou de droite n'a pas d'importance quand il n'y a qu'un seul enfant.
- Je suis sûr que c'est possible avec afinde et précommande/postorder mais je ne pense pas que c'est possible avec la précommande et postorder. Avec une seule liste, je suis certain qu'il n'est pas possible.
- Les nœuds doivent être uniques, non? Parce que sinon vous ne pouvez pas distinguer par exemple
(a, [(a, [(a, [])]), (a, [])])
et(a, [(a, []), (a, [(a, [])])])
. - Je pense que vous devez préciser que vous parlez d'arbres où un nœud peut avoir un nombre arbitraire d'enfants. Souvent, les arbres sont définis de telle sorte que chaque nœud a exactement deux enfants et une ou deux de ces peuvent être "vide". Dans ce cas, il n'est pas possible de reconstruire l'arbre de précommande et postorder parce que vous ne pouvez pas dire si un seul enfant est le gauche "enfant" ou "droit à l'enfant" (voir la discussion ici: profile.iiita.ac.in/pkmallick_03/pages/3_16.html).
- Je crois que j'en ai lu que afinde est absurde pour les non-arbres binaires.
- bien sûr, les nœuds sont uniques.
- B en Effet, les nœuds dans les arbres, je suis en train de travailler avec une quantité arbitraire d'enfants
- La solution que j'ai opérations actuelles avec une quantité arbitraire d'enfants et préserve leur commande correctement.
- Par la manière, je pense que la façon de le prouver est de contre-exemple. Supposons que la technique décrite ne fonctionne PAS, et puis trouver une contradiction. C'est vraiment juste un intestin de l'instinct, mais je pense que c'est la voie à suivre ici.
- Juste pour préciser, la preuve en contre-exemple, au mieux, vous donne une existence de preuve, pas de l'algorithme. Le problème avec "supposer qu'il ne fonctionne pas", c'est que vous avez à assumer toute et toutes les combinaisons de raisons pour lesquelles cela ne fonctionne pas.
- C'était mon Google les questions de l'entrevue 😉
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas utiliser une seule liste, parce que vous n'allez avoir aucun sens de la profondeur de l'arbre. Ainsi, vous avez certainement besoin de deux ou plusieurs listes.
Voici ma tentative de solution:
Utiliser votre précommande de la traversée comme un moyen de connaître le classement des données. Cela a un sens, parce que vous savez que le premier nœud est le top, et vous savez que de nouvelles données à la gauche de la traversée appartient à la gauche de l'arbre, etc.
Votre post afin de traversée peut déterminer la profondeur de l'arbre. Par exemple, disons que j'ai une structure comme ceci:
Nous savons que nous commencez avec 1, car il est le premier nœud dans la précommande de la traversée. Ensuite, nous regardons le prochain numéro 2. Dans le poste de commande, parce que le numéro 2 vient AVANT que le nœud 1, nous savons que 2 doit être un enfant de 1. Nous examinerons ensuite 3. 3 vient avant 2, et donc 3 est un enfant de 2. 4 est avant le 2 mais après le 3, donc nous savons que 4 est un enfant de 2, mais PAS un enfant de 3. Etc.
Maintenant, cela peut ne pas fonctionner si les nœuds ne sont pas uniques, mais à tout le moins, un début de solution.
Edit: L'ordre des enfants est préservé grâce à cette solution, tout simplement en raison de connaître l'ordre des nœuds via la précommande de la traversée, puis de connaître la structure via le postorder traversée.
Edit2: La preuve en est peut-être là: http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel2%2F215%2F626%2F00017225.pdf%3Farnumber%3D17225&authDecision=-203
Je pense que vous devez vous procurer le document, mais...
Voici une preuve écrite présentée à être une solution:
http://www14.informatik.tu-muenchen.de/lehre/2007WS/fa-cse/tutorials/tutorial09-solutions.pdf
Précommande et postorder ne pas définir unique d'un arbre.
Envisager l'arbitraire d'un arbre T que le quadruple (A, B, C, D), où A est le nœud racine, B est le nœud racine du premier enfant, C est un vecteur de non-vide, les enfants de B, et D est un vecteur de non-vide frères et sœurs de B. éléments de La C et D sont eux-mêmes des arbres.
Tout de A, B, C et D peut être vide. Si B est vide, et doit donc être C et D; si A, alors tout.
Depuis les nœuds sont uniques, les ensembles de nœuds contenus n'importe où dans C et D sont disjoints, et ne contient ni A ou B.
Fonctions pre() et post() générer des séquences ordonnées de la forme:
pre(T) = [A, B, pré(C), pré(D)]
post(T) = [post(C), B, post(D), A]
où la fonction appliquée à un vecteur est défini à la concaténation des séquences résultant de l'application de la fonction à chaque élément à son tour.
Considérons maintenant le cas:
Dans tous les cas, nous pouvons sans ambiguïté partition les membres des deux sorties de séquences en séquences, en utilisant A et B (si présent) comme délimiteurs.
La question est, peut-on également partition le vecteur des séquences? Si nous le pouvons, les uns peuvent être traitées de manière récursive et nous y sommes.
Depuis le résultat de pre() sera toujours une chaîne de séquences de départ avec Une nœuds, et le résultat de post() sera toujours une chaîne de séquences fin avec Une nœuds, en effet, on peut les diviser, fourni que l'Un des nœuds ne sont jamais vides.
C'est là que le processus tombe dans le cas binaire (voire aucune) des arbres fixes avec des enfants qui peuvent indépendamment être vide. Dans notre cas, cependant, nous avons défini C et D, ne contiennent que des non-nœuds vides, et donc la reconstruction est garanti pour fonctionner.
Euh, je pense que oui, de toute façon. Évidemment, c'est juste un argument, pas une preuve formelle!
Créer un arbre binaire avec cette restriction qui a au moins un nœud, ce nœud n'a qu'un seul enfant(de droite ou de gauche ,il n'y a pas de différence).
Maintenant, écrire son Précommande et Postorder listes. puis essayez à la reconstruction de l'arbre à partir de ces listes. et vous vous rendez compte que sur ce nœud vous ne pouvez pas décider que son enfant est à droite ou à gauche.
Comme déjà souligné par d'autres, un arbre binaire peut pas être reconstruit en utilisant uniquement des pré-et post-ordre de la traversée. Un nœud enfant unique a ambigu traversals qui ne peuvent pas déterminer si c'est la gauche ou la droite de l'enfant par exemple, envisager la suite de précommande et postorder traversals:
précommande: a,b
postorder b,un
Il peut produire à la fois des arbres suivants
un un
\ /
b b
Il n'est tout simplement pas possible de savoir si b est une droite ou gauche d'enfant sans informations supplémentaires comme afinde traversée.
La précommande et postorder traversals sont suffisantes pour permettre la reconstitution de l'arbre, en supposant que les noeuds sont particulièrement bien nommé. La clé de la création d'algorithmes de le faire est de comprendre que
Compte tenu de cela, nous pouvons toujours trouver tous les descendants d'un nœud. Les descendants de X toujours suivre immédiatement X en précommande, et précéder X dans le postorder. Donc, une fois que nous savons ce qui nous intéresse dans la production de la sous-arbre enraciné en X, on peut extraire la précommande et postorder traversal pour le sous-arbre enraciné en X. Cela conduit naturellement à un algorithme récursif, une fois que nous nous rendons compte que le nœud immédiatement après X qui doit le plus à gauche de l'enfant, si il est un descendant du tout.
Il y a aussi une pile basée sur la mise en œuvre, qui parcourt la précommande nœuds, et la maintient sur la pile tous les nœuds qui sont candidats à être le parent direct de la prochaine précommande nœud. Pour chaque précommande nœud, à plusieurs reprises pop de tous les nœuds en dehors de la pile qui ne sont pas les parents de la prochaine précommande nœud. Faire du nœud enfant du nœud supérieur sur la pile, et de pousser l'enfant dans la pile.
Il n'est pas possible de construire un général de l'Arbre Binaire de précommande et postorder traversals (Voir ceci). Mais si savoir que l'Arbre Binaire est Complet, on peut construire l'arbre sans ambiguïté. Nous comprenons ce avec l'aide de l'exemple suivant.
Considérons les deux tableaux en tant que pré[] = {1, 2, 4, 8, 9, 5, 3, 6, 7} et après[] = {8, 9, 4, 5, 2, 6, 7, 3, 1};
Dans le pré[], l'élément le plus à gauche est la racine de l'arbre. Depuis l'arbre est plein et la taille de la matrice est plus que de 1. La valeur 1 dans le pré[], doit être laissé à l'enfant de la racine. Donc, nous savons que 1 est racine et 2 est à gauche de l'enfant. Comment trouver tous les nœuds dans le sous-arbre gauche? Nous savons que 2 est une racine de tous les nœuds dans le sous-arbre gauche. Tous les nœuds avant le 2 en post[] doit être dans le sous-arbre gauche. Maintenant, nous savons que 1 est une racine, des éléments {8, 9, 4, 5, 2} sont dans le sous-arbre gauche, et les éléments de {6, 7, 3} sont dans le sous-arbre droit.
Nous récursive de suivre l'approche ci-dessus et obtenir l'arbre suivant.
4 5 6 7
/\
8 9