I'm trying to make a recursive insert method on a binary tree and while the recursive part of the function seems to do the job correctly (I tracked the code step by step with debug option) when time comes for data to be saved it just doesn't happen. Is it a reference mistake?
class TreeNode:
def __init__(self, data=None, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BTree():
def __init__(self, root=None):
self.root = root
def insert(self, data):
def in_insert(node, data):
if node is None:
node = TreeNode(data)
elif node.data == data:
print(f'{node.data} already in here.')
elif node.data > data:
node = node.left
in_insert(node, data)`
else:
node = node.right
in_insert(node, data)
if self.root is None:
self.root = TreeNode(data)
else:
in_insert(self.root, data)
You are expecting this line node = TreeNode(data)
to insert into the tree. But it's simply creating a node within the scope of the function that isn't being referenced by any other node's left
or right
.
The fix would be
class BTree():
def __init__(self, root=None):
self.root = root
def insert(self, data):
def in_insert(node, data):
if node is None:
return TreeNode(data)
elif node.data == data:
print(f'{node.data} already in here.')
elif node.data > data:
node.left = in_insert(node.left, data)
else:
node.right = in_insert(node.right, data)
return node
if self.root is None:
self.root = TreeNode(data)
else:
self.root = in_insert(self.root, data)
The changes are:
in_insert
return the node it just created if it did, or the subtree's head where the node got insertedin_insert
set its left
or right
to the newly created nodeBut what is problematic with this is that it unnecessarily assigns the left
or right
references of all the nodes involved in the path to the added node. To optimise it, you could pass the parent node to the in_insert
function to update the parent's left
or right
only at the point of insertion. Like so
class BTree():
def __init__(self, root=None):
self.root = root
def insert(self, data):
def in_insert(node, parent, is_left, data):
if node is None:
# We have found the point of insertion, time to create and insert
if is_left:
parent.left = TreeNode(data)
else:
parent.right = TreeNode(data)
elif node.data == data:
print(f'{node.data} already in here.')
elif node.data > data:
in_insert(node.left, node, True, data)
else:
in_insert(node.right, node, False, data)
if self.root is None:
self.root = TreeNode(data)
else:
in_insert(self.root, None, None, data)