Si la traversée de pré-commande d'un arbre de recherche binaire est 6, 2, 1, 4, 3, 7, 10, 9, 11, comment obtenir la traversée de post-ordre?
On vous donne la traversée en pré-ordre de l'arbre, qui se construit en faisant: sortie, traverser à gauche, traverser à droite.
Comme la traversée de post-ordre provient d'un BST, vous pouvez déduire la traversée dans l'ordre (traversée à gauche, sortie, traversée à droite) de la traversée de post-ordre en triant les nombres. Dans votre exemple, la traversée dans l'ordre est 1, 2, 3, 4, 6, 7, 9, 10, 11.
À partir de deux traversées, nous pouvons alors construire l'arbre d'origine. Prenons un exemple plus simple pour cela:
La traversée en pré-ordre nous donne la racine de l'arbre comme 2. La traversée en ordre nous dit que 1 tombe dans le sous-arbre gauche et 3, 4 tombe dans le sous-arbre droit. La structure du sous-arbre de gauche est triviale car elle contient un seul élément. Le parcours de pré-ordre du sous-arbre de droite est déduit en prenant l'ordre des éléments dans ce sous-arbre du parcours de pré-ordre d'origine: 4, 3. De cela, nous savons que la racine du sous-arbre de droite est 4 et de la traversée dans l'ordre (3, 4), nous savons que 3 tombe dans le sous-arbre gauche. Notre arbre final ressemble à ceci:
2
/ \
1 4
/
3
Avec l'arborescence, nous pouvons obtenir la traversée post-commande en parcourant l'arbre: traverser à gauche, traverser à droite, sortie. Pour cet exemple, la traversée post-commande est 1, 3, 4, 2.
Pour généraliser l'algorithme:
En utilisant l'algorithme ci-dessus, la traversée de post-ordre associée à la traversée de pré-ordre dans la question est: 1, 3, 4, 2, 9, 11, 10, 7, 6. Y arriver est laissé comme un exercice.
Pré-commande = sortie des valeurs d'un arbre binaire dans l'ordre du nœud courant, puis le sous-arbre gauche, puis le sous-arbre droit.
Post-order = sortie des valeurs d'un arbre binaire dans l'ordre du sous-arbre gauche, puis du sous-arbre droit, le nœud courant.
Dans une arborescence de recherche binaire , les valeurs de tous les nœuds du sous-arbre gauche sont inférieures à la valeur du nœud actuel; et de même pour le sous-arbre droit. Par conséquent, si vous connaissez le début d'un vidage de précommande d'un arbre de recherche binaire (c'est-à-dire la valeur de son nœud racine), vous pouvez facilement décomposer le vidage entier en la valeur du nœud racine, les valeurs des nœuds du sous-arbre gauche et les valeurs de les nœuds du sous-arbre droit.
Pour sortir l'arborescence en post-commande, la récursivité et la réorganisation de la sortie sont appliquées. Cette tâche est laissée au lecteur.
C'est le code de la traversée de précommande à post-commande en python. Je construis un arbre pour que vous puissiez trouver tout type de traversée
def postorder(root):
if root==None:
return
postorder(root.left)
print(root.data,end=" ")
postorder(root.right)
def preordertoposorder(a,n):
root=Node(a[0])
top=Node(0)
temp=Node(0)
temp=None
stack=[]
stack.append(root)
for i in range(1,len(a)):
while len(stack)!=0 and a[i]>stack[-1].data:
temp=stack.pop()
if temp!=None:
temp.right=Node(a[i])
stack.append(temp.right)
else:
stack[-1].left=Node(a[i])
stack.append(stack[-1].left)
return root
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
a=[40,30,35,80,100]
n=5
root=preordertoposorder(a,n)
postorder(root)
# print(root.data)
# print(root.left.data)
# print(root.right.data)
# print(root.left.right.data)
# print(root.right.right.data)
vous obtenez les résultats de la traversée de précommande. puis mettez les valeurs dans un arbre de recherche binaire approprié et suivez simplement l'algorithme de traversée post-commande pour le BST obtenu.
Je sais que c'est vieux mais il y a une meilleure solution.
Nous n'avons pas à reconstruire un BST pour obtenir la post-commande à partir de la pré-commande.
Voici un simple code python qui le fait récursivement:
import itertools
def postorder(preorder):
if not preorder:
return []
else:
root = preorder[0]
left = list(itertools.takewhile(lambda x: x < root, preorder[1:]))
right = preorder[len(left) + 1:]
return postorder(left) + postorder(right) + [root]
if __name__ == '__main__':
preorder = [20, 10, 6, 15, 30, 35]
print(postorder(preorder))
Sortie:
[6, 15, 10, 35, 30, 20]
Explication:
Nous savons que nous sommes en pré-commande. Cela signifie que la racine est à l'index 0
de la liste des valeurs dans le BST. Et nous savons que les éléments qui suivent la racine sont:
root
, qui appartiennent au sous-arbre gauche de la racineroot
, qui appartiennent au sous-arbre droit de la racineNous appelons alors simplement récursivement la fonction sur les deux sous-arbres (qui sont toujours en pré-ordre) puis enchaînons left + right + root
(qui est la post-commande).
Ici, la traversée en pré-commande d'un arbre de recherche binaire est donnée dans un tableau. Ainsi, le 1er élément du tableau de précommande sera racine de BST.Nous trouverons la partie gauche de BST et la partie droite de BST.Tous les éléments du tableau de précommande sont inférieurs à la racine sera le nœud gauche et tous les éléments de pré - le tableau d'ordres est plus grand que la racine sera le nœud droit.
#include <bits/stdc++.h>
using namespace std;
int arr[1002];
int no_ans = 0;
int n = 1000;
int ans[1002] ;
int k = 0;
int find_ind(int l,int r,int x){
int index = -1;
for(int i = l;i<=r;i++){
if(x<arr[i]){
index = i;
break;
}
}
if(index == -1)return index;
for(int i =l+1;i<index;i++){
if(arr[i] > x){
no_ans = 1;
return index;
}
}
for(int i = index;i<=r;i++){
if(arr[i]<x){
no_ans = 1;
return index;
}
}
return index;
}
void postorder(int l ,int r){
if(l < 0 || r >= n || l >r ) return;
ans[k++] = arr[l];
if(l==r) return;
int index = find_ind(l+1,r,arr[l]);
if(no_ans){
return;
}
if(index!=-1){
postorder(index,r);
postorder(l+1,index-1);
}
else{
postorder(l+1,r);
}
}
int main(void){
int t;
scanf("%d",&t);
while(t--){
no_ans = 0;
int n ;
scanf("%d",&n);
for(int i = 0;i<n;i++){
cin>>arr[i];
}
postorder(0,n-1);
if(no_ans){
cout<<"NO"<<endl;
}
else{
for(int i =n-1;i>=0;i--){
cout<<ans[i]<<" ";
}
cout<<endl;
}
}
return 0;
}
Si vous avez reçu une précommande et que vous souhaitez la convertir en post-commande. Ensuite, vous devez vous rappeler que dans un BST, vous devez toujours donner des nombres dans l'ordre croissant. Vous avez donc à la fois Inorder et le précommande pour construire un arbre.
pré-commander: 6, 2, 1, 4, 3, 7, 10, 9, 11
en ordre: 1, 2, 3, 4, 6, 7, 9, 10, 11
Et sa post-commande: 1 3 4 2 9 11 10 7 6
Comme nous le savons, les précommandes suivent les séries parent, left, right.
Afin de construire un arbre, nous devons suivre quelques étapes de base:
votre question consiste en séries 6, 2,1,4,3,7,10,9,11
points-:
2.Trouvez le nombre qui est supérieur à 6, donc dans cette série 7 est d'abord le plus grand nombre dans cette série, donc le nœud droit commencera d'ici et gauche jusqu'à ce nombre (7) est votre sous-arbre gauche.
6
/ \
2 7
/ \ \
1 4 10
/ / \
3 9 11
3. suivez de la même manière la règle de base de la BST, à savoir gauche, racine, droite
la série de post-commande sera L, R, N soit 1,3,4,2,9,11,10,7,6
Voici le code complet)
class Tree:
def __init__(self, data = None):
self.left = None
self.right = None
self.data = data
def add(self, data):
if self.data is None:
self.data = data
else:
if data < self.data:
if self.left is None:
self.left = Tree(data)
else:
self.left.add(data)
Elif data > self.data:
if self.right is None:
self.right = Tree(data)
else:
self.right.add(data)
def inOrder(self):
if self.data:
if self.left is not None:
self.left.inOrder()
print(self.data)
if self.right is not None:
self.right.inOrder()
def postOrder(self):
if self.data:
if self.left is not None:
self.left.postOrder()
if self.right is not None:
self.right.postOrder()
print(self.data)
def preOrder(self):
if self.data:
print(self.data)
if self.left is not None:
self.left.preOrder()
if self.right is not None:
self.right.preOrder()
arr = [6, 2, 1, 4, 3, 7, 10, 9, 11]
root = Tree()
for i in range(len(arr)):
root.add(arr[i])
print(root.inOrder())