The program should start by initializing an empty AVL tree. The program takes one line as input. Theinput line contains n “modification moves” separated by spaces (1 ≤ n ≤ 100). The available modificationmoves are:
- Aint (Character A followed by an int value between 1 and 100): A3 means insert value 3 into the AVLtree. If 3 is already in the tree, do nothing.
- Dint (Character D followed by an int value between 1 and 100): D3 means delete value 3 from the AVLtree. If 3 is not in the tree, do nothing.
Your input is then followed by exactly one Traversal Mode (PRE or POST or IN): If the Mode is PRE,then you should print out the tree (in its current situation) in pre-order. If the tree is empty, print outEMPTY. Otherwise, print out the values separated by spaces. POST and IN are handled similarly.
The Following is my main.py:
class Node: def __init__(self, key): self.left = None self.right = None self.val = key self.height = 1class AVL_Tree: def insert(self, root, key): # Step 1: Perform normal BST insertion if not root: return Node(key) elif key < root.val: root.left = self.insert(root.left, key) elif key > root.val: root.right = self.insert(root.right, key) else: # Duplicate keys are not allowed in the AVL tree return root # Step 2: Update the height of the ancestor node root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) # Step 3: Get the balance factor balance = self.getBalance(root) # Step 4: If the node becomes unbalanced, then try out the 4 cases # Left Left Case if balance > 1 and key < root.left.val: return self.rightRotate(root) # Right Right Case if balance < -1 and key > root.right.val: return self.leftRotate(root) # Left Right Case if balance > 1 and key > root.left.val: root.left = self.leftRotate(root.left) return self.rightRotate(root) # Right Left Case if balance < -1 and key < root.right.val: root.right = self.rightRotate(root.right) return self.leftRotate(root) return root def delete(self, root, key): if not root: return root if key < root.val: root.left = self.delete(root.left, key) elif key > root.val: root.right = self.delete(root.right, key) else: # Nodes with only one child or no child if root.left is None: return root.right elif root.right is None: return root.left # Node with two children: Get the inorder successor (smallest in the right subtree) temp = self.getMinValueNode(root.right) root.val = temp.val root.right = self.delete(root.right, temp.val) # If the tree had only one node then return if root is None: return root # Update the height of the current node root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) # Get the balance factor balance = self.getBalance(root) # If the node becomes unbalanced, then try out the 4 cases # Left Left Case if balance > 1 and self.getBalance(root.left) >= 0: return self.rightRotate(root) # Left Right Case if balance > 1 and self.getBalance(root.left) < 0: root.left = self.leftRotate(root.left) return self.rightRotate(root) # Right Right Case if balance < -1 and self.getBalance(root.right) <= 0: return self.leftRotate(root) # Right Left Case if balance < -1 and self.getBalance(root.right) > 0: root.right = self.rightRotate(root.right) return self.leftRotate(root) return root def leftRotate(self, z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def rightRotate(self, z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def getHeight(self, root): if not root: return 0 return root.height def getBalance(self, root): if not root: return 0 return self.getHeight(root.left) - self.getHeight(root.right) def getMinValueNode(self, root): current = root while current.left is not None: current = current.left return current def preOrder(self, root): res = [] if root: res.append(root.val) res.extend(self.preOrder(root.left)) res.extend(self.preOrder(root.right)) return res def inOrder(self, root): res = [] if root: res.extend(self.inOrder(root.left)) res.append(root.val) res.extend(self.inOrder(root.right)) return res def postOrder(self, root): res = [] if root: res.extend(self.postOrder(root.left)) res.extend(self.postOrder(root.right)) res.append(root.val) return resdef process_commands(input_line): commands = input_line.split() tree = AVL_Tree() root = None for command in commands[:-1]: # Last command is the type of traversal if command.startswith('A'): value = int(command[1:]) root = tree.insert(root, value) elif command.startswith('D'): value = int(command[1:]) root = tree.delete(root, value) # Determine the type of traversal traversal_command = commands[-1] if traversal_command == "PRE": result = tree.preOrder(root) elif traversal_command == "IN": result = tree.inOrder(root) elif traversal_command == "POST": result = tree.postOrder(root) if not result: return "EMPTY" return " ".join(map(str, result))# To run the program, you would typically wrap this in a block that takes input, e.g.:input_line = input()output = process_commands(input_line)print(output)
Right now as an example if I enter the following as an input:A1 A2 A3 A5 D3 D5 IN
The output should be:1 2
It appears to work for any case which has the traversal mode IN, but it only works partially when the traversal mode is PRE or POST. This is where I am getting stuck because I have combed through the code but I cannot understand where the issue seems to be. I just really wanted a fresh set of eyes to look at my code and tell me where I am going wrong. I have asked chatGPT but it seems to hallucinate when I ask anything remotely complicated.