0% found this document useful (0 votes)
6 views

Update Function Lang

Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Update Function Lang

Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

import re

from collections import deque

class TreeNode:
def __init__(self, value):
if not isinstance(value, int) or value < 0 or value >= 100:
raise ValueError("Node value must be a whole non-negative integer less
than 100.")
self.value = value
self.left = None
self.right = None
self.parent = None

class Tree:
def __init__(self, root_value):
self.root = TreeNode(root_value)

def add(self, parent_value, child_value):


if not isinstance(child_value, int) or child_value < 0 or child_value >=
100:
raise ValueError("Child value must be a whole non-negative integer less
than 100.")
if child_value == self.root.value:
raise ValueError("Child value cannot be the same as the root value.
Please enter a different value.")

# Check if the parent node exists


parent_node = self.find_node(self.root, parent_value)
if not parent_node:
raise ValueError(f"Parent node with value {parent_value} not found.")

# Prevent adding duplicate values


if self.find_node(self.root, child_value):
raise ValueError("Child value already exists in the tree.")

# Logic for adding the child node


if child_value < parent_node.value:
# Go to left child
if parent_node.left is None:
parent_node.left = TreeNode(child_value)
parent_node.left.parent = parent_node
else:
self.add(parent_node.left.value, child_value)
else:
# Go to right child
if parent_node.right is None:
parent_node.right = TreeNode(child_value)
parent_node.right.parent = parent_node
else:
self.add(parent_node.right.value, child_value)

print("Child added successfully.")


self.display_tree()

def _insert_node(self, node, child_value):


if child_value < node.value:
if node.left is None:
node.left = TreeNode(child_value)
node.left.parent = node
else:
raise ValueError(f"Node with value {node.value} already has a left
child.")
elif child_value > node.value:
if node.right is None:
node.right = TreeNode(child_value)
node.right.parent = node
else:
raise ValueError(f"Node with value {node.value} already has a right
child.")

def find_node(self, current_node, value):


if current_node is None:
return None
if current_node.value == value:
return current_node
left_result = self.find_node(current_node.left, value)
if left_result is not None:
return left_result
return self.find_node(current_node.right, value)

def update(self, old_value, new_value):


if not isinstance(new_value, int) or new_value < 0 or new_value >= 100:
raise ValueError("New value must be a whole non-negative integer less
than 100.")

node_to_update = self.find_node(self.root, old_value)


if node_to_update is None:
raise ValueError(f"Node with value {old_value} not found.")

parent = node_to_update.parent

# Ensure the new value does not violate the BST property with respect to
the parent
if parent:
if parent.left == node_to_update and new_value >= parent.value:
raise ValueError("The new value should be less than the parent.")
elif parent.right == node_to_update and new_value <= parent.value:
raise ValueError("The new value should be greater than the
parent.")

# If both left and right children exist, check if new_value is within their
range
if node_to_update.left and node_to_update.right:
if not (node_to_update.left.value < new_value <
node_to_update.right.value):
raise ValueError("The new value should be greater than the left
child and less than the right child.")
# If only the left child exists, ensure new_value is greater than it
elif node_to_update.left:
if new_value <= node_to_update.left.value:
raise ValueError("The new value should be greater than the left
child.")
# If only the right child exists, ensure new_value is less than it
elif node_to_update.right:
if new_value >= node_to_update.right.value:
raise ValueError("The new value should be less than the right
child.")
# Update the node value if all checks pass
node_to_update.value = new_value
print("Node updated successfully.")
self.display_tree()

def delete(self, value):


if value == self.root.value:
raise ValueError("Cannot delete the root node.")
self.root = self._delete_recursive(self.root, value)
print(f"Node with value {value} deleted.")
self.display_tree()

def _delete_recursive(self, node, value):


if node is None:
raise ValueError(f"Node with value {value} not found.")

if value < node.value:


node.left = self._delete_recursive(node.left, value)
elif value > node.value:
node.right = self._delete_recursive(node.right, value)
else:
if node.left and node.right:
replacement = node.left
max_left = self._find_max(replacement)
max_left.right = node.right
node = replacement
elif node.left:
node = node.left
elif node.right:
node = node.right
else:
return None
return node

def _find_max(self, node):


current = node
while current.right is not None:
current = current.right
return current

def display_tree(self):
if self.root is None:
print("Empty tree")
return

levels = self._get_levels(self.root)
output = []

for level in levels:


row = []
for node, spacing in level:
if node:
label = "root: " if node == self.root else ("L: " if node.value
< node.parent.value else "R: ")
row.append(f"{label}{node.value}".center(spacing))
else:
row.append(" " * spacing)
output.append("".join(row))
print("\nCurrent Tree Structure:")
for line in output:
print(line)

def display_subtree(self, node_value):


subtree_root = self.find_node(self.root, node_value)
if subtree_root is None:
print(f"No node with value {node_value} found.")
return

print(f"\nDisplaying Subtree rooted at {node_value}:")


subtree = Tree(subtree_root.value) # Temporary tree to visualize subtree
only
subtree.root = subtree_root
subtree.display_tree()

def display_leaf_nodes(self):
print("\nLeaf Nodes:")
self._print_leaf_nodes(self.root)

def _print_leaf_nodes(self, node):


if node:
if not node.left and not node.right:
print(node.value)
self._print_leaf_nodes(node.left)
self._print_leaf_nodes(node.right)

def display_siblings(self, parent_value):


parent_node = self.find_node(self.root, parent_value)
if not parent_node:
print(f"Parent node with value {parent_value} not found.")
return
siblings = []
if parent_node.left:
siblings.append(parent_node.left.value)
if parent_node.right:
siblings.append(parent_node.right.value)
if siblings:
print(f"Siblings of {parent_value}: {', '.join(map(str, siblings))}")
else:
print("No siblings found.")

def display_root(self):
print(f"\nRoot Node: {self.root.value}")

def display_parents(self):
print("\nParent Nodes:")
self._print_parents(self.root)

def _print_parents(self, node):


if node:
if node.left or node.right:
print(node.value)
self._print_parents(node.left)
self._print_parents(node.right)

def display_children(self):
print("\nChild Nodes:")
self._print_children(self.root)

def _print_children(self, node):


if node:
if node.left:
print(node.left.value)
if node.right:
print(node.right.value)
self._print_children(node.left)
self._print_children(node.right)

def tree_level(self):
print("\nTree Level (Height):", self._get_tree_level(self.root))

def _get_tree_level(self, node):


if node is None:
return 0
return max(self._get_tree_level(node.left),
self._get_tree_level(node.right)) + 1

def _get_levels(self, root):


levels = []
queue = deque([(root, 0)])
max_depth = self._get_tree_level(root)

while queue:
level_size = len(queue)
level = []

for _ in range(level_size):
node, depth = queue.popleft()
spacing = (2 ** (max_depth - depth + 1)) - 1
level.append((node, spacing))

if node:
if node.left:
node.left.parent = node
if node.right:
node.right.parent = node
queue.append((node.left, depth + 1))
queue.append((node.right, depth + 1))
levels.append(level)
return levels

def main():
while True:
root_value = input("Enter the root value (must be a whole number < 100):
").strip()
if re.match(r"^(1|[1-9][0-9]?)$", root_value):
root_value = int(root_value)
break
else:
print("Invalid input. Please enter a whole number between 1 and 99.")

tree = Tree(root_value)
tree.display_tree()

while True:
print("\nAvailable commands:")
print("add <parent> <child> - Add a child node")
print("update <old> <new> - Update a node's value")
print("delete <node> - Delete a node")
print("display_leaf_nodes - Display all leaf nodes")
print("display_siblings <parent> - Display siblings of given parent node")
print("display_root - Display root node")
print("display_parents - Display all parent nodes")
print("display_children - Display all child nodes")
print("tree_level - Display the level (height) of the tree")
print("display_tree - Display the current tree structure")
print("display_subtree <node> - Display the subtree rooted at a given
node")
print("exit - Exit the program")

command_input = input("Enter command: ").strip()


command_parts = command_input.split()
if not command_parts:
continue

command = command_parts[0].lower()

try:
if command == "add" and len(command_parts) == 3:
parent_value = int(command_parts[1])
child_value = int(command_parts[2])
tree.add(parent_value, child_value)
elif command == "update" and len(command_parts) == 3:
old_value = int(command_parts[1])
new_value = int(command_parts[2])
tree.update(old_value, new_value)
elif command == "delete" and len(command_parts) == 2:
node_value = int(command_parts[1])
tree.delete(node_value)
elif command == "leafNodes":
tree.display_leaf_nodes()
elif command == "siblings" and len(command_parts) == 2:
parent_value = int(command_parts[1])
tree.display_siblings(parent_value)
elif command == "root":
tree.display_root()
elif command == "parents":
tree.display_parents()
elif command == "children":
tree.display_children()
elif command == "level":
tree.tree_level()
elif command == "display tree":
tree.display_tree()
elif command == "subtree" and len(command_parts) == 2:
node_value = int(command_parts[1])
tree.display_subtree(node_value)
elif command == "exit":
print("Exiting...")
break
else:
print("Invalid command or wrong number of arguments.")
except ValueError as e:
print("Error:", e)
if __name__ == "__main__":
main()

You might also like