Skip to content

Instantly share code, notes, and snippets.

@victorusachev
Created October 17, 2019 07:37
Show Gist options
  • Select an option

  • Save victorusachev/62ab149798a51ae02b99c5f9081a1bd3 to your computer and use it in GitHub Desktop.

Select an option

Save victorusachev/62ab149798a51ae02b99c5f9081a1bd3 to your computer and use it in GitHub Desktop.
import enum
class BinaryNode:
def __init__(self, data, parent=None):
self.data = data
self._parent = parent
self._left = None
self._right = None
@property
def parent(self):
return self._parent
@property
def left(self):
return self._left
@property
def right(self):
return self._right
@left.setter
def left(self, data):
if self._left:
raise ValueError('the left node already exists')
self._left = BinaryNode(data, parent=self)
@right.setter
def right(self, data):
if self._right:
raise ValueError('the right node already exists')
self._right = BinaryNode(data, parent=self)
def __eq__(self, other):
return self.data == other.data
def __ne__(self, other):
return self.data != other.data
def __gt__(self, other):
return self.data > other.data
def __lt__(self, other):
return self.data < other.data
def __ge__(self, other):
return self.data >= other.data
def __le__(self, other):
return self.data <= other.data
def __hash__(self):
return hash(self.data)
def __str__(self):
return str(self.data)
class BinaryTree:
def __init__(self, data):
self.root = BinaryNode(data)
def insert(self, data):
node = self.root
while node.right:
node = node.right
node.right = data
node = node.right
while node.parent:
if node < node.parent:
node.parent.data, node.data = node.data, node.parent.data
node = node.parent
class BinaryTreeTraversal:
class MODES(enum.Enum):
IN = 'in'
PRE = 'pre'
POST = 'post'
def __init__(self, visit_func=None, order=MODES.IN):
self.order = order
self.visit_func = visit_func
def _validate_order(self, order):
if order in self.MODES:
return True
raise ValueError(f'specified order is not supported: {order}')
def _validate_visit_func(self, func):
if not callable(func):
raise ValueError
return True
@property
def order(self):
return self._order
@order.setter
def order(self, value):
self._validate_order(value)
self._order = value
@property
def visit_func(self):
return self._visit_func
@visit_func.setter
def visit_func(self, value):
self._validate_visit_func(value)
self._visit_func = value
def visit(self, node):
self._visit_func(node)
def traversal(self, node, order=None):
if not node:
return
if order:
self._validate_order(order)
children = iter((node.left, node.right))
for o in self.MODES:
if o == (order or self.order):
self.visit(node)
else:
self.traversal(next(children))
def main():
tree = BinaryTree(4)
root = tree.root
root.left = 50
root.left.left = 55
root.left.right = 90
root.right = 7
root.right.left = 87
traversal = BinaryTreeTraversal(visit_func=print)
traversal.traversal(tree.root)
print('Insert node with value `2`')
tree.insert(2)
tree.insert(2)
tree.insert(2)
tree.insert(10)
traversal.traversal(tree.root)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment