Created
October 17, 2019 07:37
-
-
Save victorusachev/62ab149798a51ae02b99c5f9081a1bd3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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