Comparer les arbres à l' aide approche Canonisation suggérée par @mcdowella . La différence est que mon approche ne nécessite pas le O(N)numéro de WRT mémoire supplémentaire de nœuds dans l'arborescence:
# in Python
from collections import namedtuple
from itertools import chain
# Tree is either None or a tuple of its value and left, right trees
Tree = namedtuple('Tree', 'value left right')
def canonorder(a, b):
"""Sort nodes a, b by their values.
`None` goes to the left
"""
if (a and b and a.value > b.value) or b is None:
a, b = b, a # swap
return a, b
def canonwalk(tree, canonorder=canonorder):
"""Yield all tree nodes in a canonical order.
Bottom-up, smaller children first, None is the smallest
"""
if tree is not None:
children = tree[1:]
if all(t is None for t in children): return # cut None leaves
children = canonorder(*children)
for child in chain(*map(canonwalk, children)):
yield child
yield tree
canonwalk()nécessite des O(N*M)étapes et la O(log(N)*M)mémoire pour donner tous les noeuds dans un arbre, où Nest le nombre total de noeuds, le Mnombre d'enfants chaque noeud a (il est 2 pour les arbres binaires).
canonorder()pourrait facilement être généralisé pour toute représentation de noeud et un certain nombre d'enfants. canonwalk()exige seulement qu'un arbre peut accéder à ses enfants immédiats comme une séquence.
La fonction de comparaison qui appelle canonwalk():
from itertools import imap, izip_longest
unset = object()
def cmptree(*trees):
unequal = False # allow root nodes to be unequal
# traverse in parallel all trees under comparison
for nodes in izip_longest(*imap(canonwalk, trees), fillvalue=unset):
if unequal:
return False # children nodes are not equal
if any(t is unset for t in nodes):
return False # different number of nodes
if all(t is not None for t in nodes):
unequal = any(nodes[-1].value != t.value for t in nodes)
else: # some are None
unequal = any(t is not None for t in nodes)
return True # equal
Exemple
5 6
/ \ / \ they are equal.
1 2 2 1
/ \ / /
3 4 4 3
tree1 = Tree(5,
Tree(1,
Tree(3, None,None), None),
Tree(2,
None, Tree(4, None, None)))
tree2 = Tree(6,
Tree(2, Tree(4, None, None), None),
Tree(1, Tree(3, None, None), None))
print cmptree(tree1, tree2)
Sortie
True