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

Update Function Lang

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
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
We take content rights seriously. If you suspect this is your content, claim it here.
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