Source code for tree_sort.funcs

"""
Examples of binary tree, made in the style of OOP

It's just example of binary sort functions, based or not on his own tree.
"""

from abc import ABCMeta, abstractmethod
from collections.abc import Iterator
from numbers import Integral
import bisect


[docs]class BaseNodeClass(metaclass=ABCMeta): """ Abstract Binary Tree Class All other based on this interface """
[docs] @abstractmethod def add_node(self, data: Integral) -> None: """ add items to data container """ raise NotImplementedError
[docs] @abstractmethod def tree_data(self) -> Iterator: """ return sorted items of inner data """ raise NotImplementedError
[docs]class BisectNodeClass(BaseNodeClass): """ Based on bisect stdlib, without inner tree """ def __init__(self): self.data = [] # @profile
[docs] def add_node(self, data: Integral) -> None: bisect.insort(self.data, data)
# @profile
[docs] def tree_data(self) -> Iterator: yield from self.data
[docs]class SingleNodeClass(BaseNodeClass): """ All operations and storage takes place inside one class """ def __init__(self, data: Integral = None): self.left = None self.right = None self.data = data # @profile
[docs] def add_node(self, data: Integral) -> None: if self.data is not None: if data < self.data: if self.left is None: self.left = SingleNodeClass(data) else: self.left.add_node(data) elif data > self.data: if self.right is None: self.right = SingleNodeClass(data) else: self.right.add_node(data) else: self.data = data
# @profile
[docs] def tree_data(self) -> Iterator: if self.left: yield from self.left.tree_data() yield self.data if self.right: yield from self.right.tree_data()
[docs]class TwoNodeClass(BaseNodeClass): """ Use inner class Node for storage and TwoNodeClass for for everything else based on https://gist.github.com/samidhtalsania/6659380 """
[docs] class Node: """ Inner class of item, which contain info about neightbours """ def __init__(self, key: Integral): self.key = key self.left = None self.right = None self.parent = None
def __init__(self): self.root = None # @profile
[docs] def add_node(self, key: Integral, _node: Node = None) -> None: if _node is None: _node = self.root if self.root is None: self.root = self.Node(key) else: if key <= _node.key: if _node.left is None: _node.left = self.Node(key) _node.left.parent = _node return else: return self.add_node(key, _node=_node.left) else: if _node.right is None: _node.right = self.Node(key) _node.right.parent = _node return else: return self.add_node(key, _node=_node.right)
# @profile
[docs] def tree_data(self, _node: Node = None) -> Iterator: if _node is None: _node = self.root stack = [] while stack or _node: if _node is not None: stack.append(_node) _node = _node.left else: _node = stack.pop() yield _node.key _node = _node.right
def profile(): import time from tree_sort.data import datalist_100 nodes = [SingleNodeClass, TwoNodeClass, BisectNodeClass] for cls_node in nodes: node = cls_node() for i in datalist_100: node.add_node(i) list(node.tree_data()) time.sleep(0.3) if __name__ == '__main__': profile()