|
| 1 | +class TreeNode: |
| 2 | + def __init__(self, value): |
| 3 | + self.value = value |
| 4 | + self.left = None |
| 5 | + self.right = None |
| 6 | + |
| 7 | + |
| 8 | +class BinaryTree: |
| 9 | + def __init__(self): |
| 10 | + self.root = None |
| 11 | + |
| 12 | + def add_node(self, value, parent_value, is_left): |
| 13 | + # Add a node to the tree |
| 14 | + if self.root is None: |
| 15 | + self.root = TreeNode(value) |
| 16 | + else: |
| 17 | + parent_node = self._find_node(self.root, parent_value) |
| 18 | + if parent_node: |
| 19 | + new_node = TreeNode(value) |
| 20 | + if is_left: |
| 21 | + parent_node.left = new_node |
| 22 | + else: |
| 23 | + parent_node.right = new_node |
| 24 | + else: |
| 25 | + print("Parent node not found.") |
| 26 | + |
| 27 | + def _find_node(self, current, value): |
| 28 | + # Helper function to find a node with a given value |
| 29 | + if current is None: |
| 30 | + return None |
| 31 | + if current.value == value: |
| 32 | + return current |
| 33 | + left = self._find_node(current.left, value) |
| 34 | + if left: |
| 35 | + return left |
| 36 | + return self._find_node(current.right, value) |
| 37 | + |
| 38 | + def lca(self, root, n1, n2): |
| 39 | + # Function to find LCA of n1 and n2 |
| 40 | + if root is None: |
| 41 | + return None |
| 42 | + if root.value == n1 or root.value == n2: |
| 43 | + return root |
| 44 | + |
| 45 | + left_lca = self.lca(root.left, n1, n2) |
| 46 | + right_lca = self.lca(root.right, n1, n2) |
| 47 | + |
| 48 | + if left_lca and right_lca: |
| 49 | + return root |
| 50 | + |
| 51 | + return left_lca if left_lca else right_lca |
| 52 | + |
| 53 | + def find_lca(self, n1, n2): |
| 54 | + # Public method to find LCA of two nodes |
| 55 | + lca_node = self.lca(self.root, n1, n2) |
| 56 | + if lca_node: |
| 57 | + return lca_node.value |
| 58 | + else: |
| 59 | + return None |
| 60 | + |
| 61 | + |
| 62 | +def menu(): |
| 63 | + bt = BinaryTree() # Create a new BinaryTree instance |
| 64 | + while True: |
| 65 | + print("\n1. Add Node\n2. Find LCA\n3. Exit") |
| 66 | + choice = int(input("Choose an option: ")) |
| 67 | + |
| 68 | + if choice == 1: |
| 69 | + value = int(input("Enter node value: ")) |
| 70 | + if bt.root is None: |
| 71 | + # If the tree is empty, make this the root node |
| 72 | + bt.add_node(value, None, None) |
| 73 | + print(f"Node {value} added as root.") |
| 74 | + else: |
| 75 | + parent_value = int(input("Enter parent node value: ")) |
| 76 | + is_left = input("Is this a left child? (y/n): ").lower() == 'y' |
| 77 | + bt.add_node(value, parent_value, is_left) |
| 78 | + print(f"Node {value} added as {'left' if is_left else 'right'} child of {parent_value}.") |
| 79 | + |
| 80 | + elif choice == 2: |
| 81 | + n1 = int(input("Enter first node value: ")) |
| 82 | + n2 = int(input("Enter second node value: ")) |
| 83 | + lca_value = bt.find_lca(n1, n2) |
| 84 | + if lca_value is not None: |
| 85 | + print(f"The Lowest Common Ancestor of {n1} and {n2} is: {lca_value}") |
| 86 | + else: |
| 87 | + print(f"One or both nodes not found in the tree.") |
| 88 | + |
| 89 | + elif choice == 3: |
| 90 | + print("Exiting...") |
| 91 | + break |
| 92 | + |
| 93 | + else: |
| 94 | + print("Invalid choice!") |
| 95 | + |
| 96 | + |
| 97 | +if __name__ == "__main__": |
| 98 | + menu() |
0 commit comments