Source code for python_lib_examples.binary_tree
from typing import Optional
[docs]
class BinaryTree:
def __init__(
self,
value: int = 0,
left: Optional[object] = None,
right: Optional[object] = None,
):
assert isinstance(value, int), f"{type(value)} is not int"
self.value = value
self.left = left
self.right = right
def _construct_layer_from_list(self, layer: int, parents: list[object],
node_values: list[int]):
"""
construct one layer of the binary tree from node value list.
return nodes of this layer, with None represents empty nodes.
"""
nodes = []
assert (node_values is not None
and len(node_values) > 0), f"{node_values} is None or empty"
if layer == 0:
self.value = node_values[0]
# assume only root node will call _construct_layer_from_list().
return [self]
# 0 layer 0
# / \
# 1 2 layer 1
# /\ /\
# 3 4 5 6 layer 2
assert len(parents) == 2**(
layer -
1), f"len(parents): {len(parents)} != 2 ** (layer: {layer} - 1)"
for i in range(len(node_values)):
# use (i - 1) % len(parents) to get the right parent index
if node_values[i] is not None:
node = BinaryTree(node_values[i])
p_i = i // 2
assert parents[p_i] is not None
if i % 2 == 0:
parents[p_i].left = node
else:
parents[p_i].right = node
print(f"parents[p_i]:{str(parents[p_i])}")
nodes.append(node)
else:
nodes.append(None)
return nodes
[docs]
def construct_from_list(self, arr: list):
"""
given list of arr of each layer of the tree,
None represents empty tree node.
construct the tree.
"""
if arr is None or len(arr) == 0:
return False
# arr[i] is a fixed position in binary tree.
# create this tree node and put it to the right position.
# 0
# / \
# 1 2
# /\ /\
# 3 4 5 6
parents = []
layer = 0
start_index = 0
while start_index < len(arr):
end_index = start_index + 2**layer
print(f"start_index:{start_index}, end_index: {end_index}")
print(f"arr[start_index:end_index]:{arr[start_index:end_index]}")
print(f"parents:{str(parents)}")
nodes = self._construct_layer_from_list(layer, parents,
arr[start_index:end_index])
print(f"binary_tree: {self.__str__()}")
parents = nodes
layer += 1
start_index = 2**layer - 1
return True
[docs]
def preorder_str(self) -> str:
s = ""
if self.left is not None:
s = self.left.preorder_str()
s += str(self.value)
if self.right is not None:
s += self.right.preorder_str()
return s
[docs]
def inorder_str(self) -> str:
s = str(self.value)
if self.left is not None:
s += self.left.inorder_str()
if self.right is not None:
s += self.right.inorder_str()
return s
[docs]
def postorder_str(self) -> str:
s = ""
if self.left is not None:
s += self.left.postorder_str()
if self.right is not None:
s += self.right.postorder_str()
s += str(self.value)
return s
__str__ = inorder_str
[docs]
def test_binary_tree():
# 0
# / \
# 1 2
# /\ /\
# 3 4 5 6
bt = BinaryTree(0)
bt.left = BinaryTree(1)
bt.right = BinaryTree(2)
bt.left.left = BinaryTree(3)
bt.left.right = BinaryTree(4)
bt.right.left = BinaryTree(5)
bt.right.right = BinaryTree(6)
print(f"preorder: {bt.preorder_str()}")
assert bt.preorder_str() == "3140526", f"{bt.preorder_str()} != '3140526'"
print(f"inorder: {bt.inorder_str()}")
print(f"postorder: {bt.postorder_str()}")
[docs]
def test_construct_binary_tree():
# 0
# / \
# 1 2
# /\ /\
# 3 4 5 6
arr = [0, 1, 2, 3, 4, 5, 6]
bt = BinaryTree()
bt.construct_from_list(arr)
print(f"preorder: {bt.preorder_str()}")
print(f"inorder: {bt.inorder_str()}")
print(f"postorder: {bt.postorder_str()}")
assert bt.inorder_str(
) == "0134256", f"bt.inorder_str():{bt.inorder_str()}"
# 0
# / \
# 1 N
# /\ /\
# 3 4 N N
arr = [0, 1, None, 3, 4]
bt = BinaryTree()
bt.construct_from_list(arr)
assert bt.inorder_str() == "0134", f"bt.inorder_str():{bt.inorder_str()}"
# 0
# / \
# 1 2
# /\ / \
# 3 4 N 6
# /\ /\ / \
# N N N N N N 7 8
arr = [0, 1, 2, 3, 4, None, 6, None, None, None, None, None, None, 7, 8]
bt = BinaryTree()
bt.construct_from_list(arr)
assert bt.inorder_str(
) == "01342678", f"bt.inorder_str():{bt.inorder_str()}"
if __name__ == "__main__":
# test_binary_tree()
test_construct_binary_tree()