#! /usr/bin/python3
# ==================================================================
# create a binary search tree with multiple node types
#
# Notes:
# 1. To simplify the code, all of the nodes have a common key
# (an integer) for node comparison/insertion. (A sophisticated
# comparison method could be developed.)
# 2. Nodes are created outside of the binary tree code and inserted
# into the tree. Thus, The binary tree code is not responsible
# for the node's correctness.
# 3. Perhaps one way to make the code less confusing to read
# is for each node have a method to get it's key?
# ==================================================================
class NodeInum:
'''integer data object'''
def __init__(self, key, inum):
self.key = key
self.left = None
self.right = None
self.inum = inum
class NodeFnum:
'''float data object'''
def __init__(self, key, fnum):
self.key = key
self.left = None
self.right = None
self.fnum = fnum
class NodeStr:
'''string data object'''
def __init__(self, key, str):
self.key = key
self.left = None
self.right = None
self.str = str
class NodeUnk:
'''unknow data object (for debug testing)'''
def __init__(self, key, data):
self.key = key
self.left = None
self.right = None
self.data = data
class BinaryTree:
'''binary tree object'''
# ---- init object --------------------------
def __init__(self):
self.root = None
# ---- insert object into tree --------------
def insert(self,newnode):
if self.root == None:
self.root = newnode
else:
self._insert(newnode,self.root)
def _insert(self,newnode,curnode):
if newnode.key < curnode.key:
if curnode.left == None:
curnode.left = newnode
else:
self._insert(newnode,curnode.left)
elif newnode.key > curnode.key:
if curnode.right == None:
curnode.right = newnode
else:
self._insert(newnode,curnode.right)
else:
print("Tree node " + str(curnode.key) +
" already in the tree")
# ---- print tree ---------------------------
def PrintTree(self):
if self.root == None:
print("tree empty")
else:
self._PrintTree(self.root)
def _PrintTreeNode(self,node):
if isinstance(node,NodeInum):
print("node (key={}) type NodeInum ({})".
format(str(node.key),str(node.inum)))
elif isinstance(node,NodeFnum):
print("node (key={}) type NodeFnum ({})".
format(str(node.key),str(node.fnum)))
elif isinstance(node,NodeStr):
print("node (key={}) type NodeStr ({})".
format(str(node.key),node.str))
else:
print("node (key={}) type unknown type={}".
format(str(node.key),type(node).__name__))
return False
return True
def _PrintTree(self,curnode):
if curnode.left:
self._PrintTree(curnode.left)
if not self._PrintTreeNode(curnode):
pass ##return
if curnode.right:
self._PrintTree(curnode.right)
# ---- print tree structure -----------------
def PrintTreeStructure(self):
if self.root == None:
print("tree empty")
else:
self._PrintTreeStructure(self.root,1)
def _PrintTreeStructureNode(self,node,n):
if isinstance(node,NodeInum):
print('({}) {} {}'.format(str(node.key),
'---'*n,str(node.inum)))
elif isinstance(node,NodeFnum):
print('({}) {} {}'.format(str(node.key),
'---'*n,str(node.fnum)))
elif isinstance(node,NodeStr):
print('({}) {} {}'.format(str(node.key),
'---'*n,node.str))
else:
print('({}) {} {}'.format(str(node.key),
'---'*n,' unknow'))
return False
return True
def _PrintTreeStructure(self,curnode,n):
if curnode.right:
self._PrintTreeStructure(curnode.right,n+1)
if not self._PrintTreeStructureNode(curnode,n):
pass ##return
if curnode.left:
self._PrintTreeStructure(curnode.left,n+1)
# ---- test tree 1
tree = BinaryTree()
tree.insert(NodeInum(6,12)) # root node
tree.insert(NodeFnum(3,3.13159))
tree.insert(NodeStr(5,"abc"))
tree.insert(NodeUnk(4,"unk"))
tree.insert(NodeInum(7,666))
tree.insert(NodeFnum(9,2.71828))
tree.insert(NodeStr(8,"xyz"))
tree.insert(NodeInum(1,"102"))
print("-----------------------------------------------------")
tree.PrintTree()
print("-----------------------------------------------------")
tree.PrintTreeStructure()
print("-----------------------------------------------------")