class Tree:
LEAVES = 0
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
self.node_order = []
self.increment_leaves()
def clear_node_order(self):
self.node_order.clear()
def traverse_inorder(self, tree):
if tree:
self.traverse_inorder(tree.left)
self.node_order.append(str(tree.value))
self.traverse_inorder(tree.right)
return ''.join(self.node_order)
def traverse_preorder(self, tree):
if tree:
self.node_order.append(str(tree.value))
self.traverse_preorder(tree.left)
self.traverse_preorder(tree.right)
return ''.join(self.node_order)
def traverse_postorder(self, tree):
if tree:
self.traverse_postorder(tree.left)
self.traverse_postorder(tree.right)
self.node_order.append(str(tree.value))
return ''.join(self.node_order)
def get_deepest_node(self, tree, level = 0, maxlevel=[-1], curr_deepest=[-1]):
if tree:
level += 1
self.get_deepest_node(tree.left, level, maxlevel, curr_deepest)
if level > maxlevel[0]:
curr_deepest[0] = tree.value
maxlevel[0] = level
self.get_deepest_node(tree.right, level, maxlevel, curr_deepest)
return curr_deepest[0]
def get_levels(self, tree):
target = self.get_deepest_node(tree)
queue = []
level = 1
queue.append(tree)
queue.append(None)
while len(queue):
curr_node = queue[0]
queue.pop(0)
if not curr_node:
if len(queue) == 0:
return 0
if queue[0]:
queue.append(None)
level += 1
else:
if curr_node.value == target:
return level
if curr_node.left:
queue.append(curr_node.left)
if curr_node.right:
queue.append(curr_node.right)
return 0
@classmethod
def increment_leaves(cls):
cls.LEAVES += 1
@staticmethod
def help():
return """
This help method is a staticmethod
"""
def mirror(tree):
if tree:
tree.right, tree.left = tree.left, tree.right
try:
mirror(tree.left)
mirror(tree.right)
except:
pass
return tree
tree = Tree(1)
tree.left = Tree(2)
tree.right = Tree(3)
tree.left.left = Tree(4)
tree.left.right = Tree(5)
tree.right.left = Tree(6)
tree.right.right = Tree(7)
tree.left.right.left = Tree(8)
tree.left.right.right = Tree(9)
tree.left.right.right.left = Tree('a')
tree.left.right.right.right = Tree('b')
print(f'Original Tree: Node ID: {hex(id(tree))}')
print(tree.traverse_inorder(tree))
tree.clear_node_order()
tree = mirror(tree)
print()
print(f'Mirrored Tree: Node ID: {hex(id(tree))}')
print(tree.traverse_inorder(tree))
tree.clear_node_order()
print()
print(f'Leaves: {tree.LEAVES}')
print(f'Help method bound to instance: {tree.help()}')
print(f'Help method bound to class: {tree.help()}')
print(f'Levels: {tree.get_levels(tree)}')
# Tests
test_tree = Tree(3)
assert test_tree.value == 3, 'Should be 3'
order_nodes = Tree(3)
order_nodes.left = Tree(4)
order_nodes.right = Tree(5)
assert order_nodes.traverse_inorder(order_nodes) == '435', 'should be 354'
order_nodes.clear_node_order()
assert order_nodes.traverse_preorder(order_nodes) == '345', 'should be 345'
order_nodes.clear_node_order()
assert order_nodes.traverse_postorder(order_nodes) == '453', 'should be 453'
Ouptputs:
Original Tree: Node ID: 0x7f09f0381f28
4285a9b1637
Mirrored Tree: Node ID: 0x7f09f0381f28
7361b9a5824
Leaves: 11
Help method bound to instance (tree):
This help method is a staticmethod
Help method bound to class (Tree):
This help method is a staticmethod
Levels: 5
Tree:
1
/ \
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7
/ \
8 9
/ \
a b