Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 16624

I am trying to implement an AVL Tree in a python script. the tree can be traversed in ( Pre-order, In-order and Post-order)

$
0
0

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.


Viewing all articles
Browse latest Browse all 16624

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>