• + 0 comments

    `

    class Node: def init(self, data): self.data = data self.left = None self.right = None self.height = 1 self.size = 1

    class AVLTree: def init(self): self.root = None

    def getMedian(self):
        if not self.root:
            return None
    
        if self.root.size % 2 == 0:
            m1 = self.root.size // 2
            m2 = m1 + 1
            median_value = (self.findNthElement(m1) + self.findNthElement(m2)) / 2
        else:
            median_value = self.findNthElement(self.root.size // 2 + 1)
    
        return self.formatNumber(median_value)
    
    def findNthElement(self, n):
        node = self.root
        while node:
            left_size = self.getSize(node.left)
            if n <= left_size:
                node = node.left
            elif n == left_size + 1:
                return node.data
            else:
                n -= left_size + 1
                node = node.right
        return None
    
    def formatNumber(self, num):
        if num == int(num):
            return str(int(num))
        return str(num).rstrip("0").rstrip(".")
    
    def insert(self, data):
        self.root = self._insert(self.root, data)
        median_value = self.getMedian()
        if median_value is not None:
            print(median_value)
        else:
            print("Wrong!")
    
    def _insert(self, node, data):
        if not node:
            return Node(data)
    
        if data < node.data:
            node.left = self._insert(node.left, data)
        else:
            node.right = self._insert(node.right, data)
    
        node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right))
        node.size = 1 + self.getSize(node.left) + self.getSize(node.right)
    
        return self._rebalance(node)
    
    def delete(self, data):
        if not self.root:
            print("Wrong!")
            return
    
        initial_size = self.root.size
        self.root = self._delete(self.root, data)
        if self.root and self.root.size == initial_size:
            print("Wrong!")
        else:
            median_value = self.getMedian()
            if median_value is not None:
                print(median_value)
            else:
                print("Wrong!")
    
    def _delete(self, node, data):
        if not node:
            return node
    
        if data < node.data:
            node.left = self._delete(node.left, data)
        elif data > node.data:
            node.right = self._delete(node.right, data)
        else:
            if not node.left:
                return node.right
            elif not node.right:
                return node.left
    
            inorder_successor = self.findInorderSuccessor(node)
            node.data = inorder_successor.data
            node.right = self._delete(node.right, inorder_successor.data)
    
        node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right))
        node.size = 1 + self.getSize(node.left) + self.getSize(node.right)
    
        return self._rebalance(node)
    
    def findInorderSuccessor(self, node):
        current = node.right
        while current.left:
            current = current.left
        return current
    
    def _rebalance(self, node):
        bf = self.getBalanceFactor(node)
    
        if bf > 1 and self.getBalanceFactor(node.left) >= 0:
            return self.rotateRight(node)
    
        if bf > 1 and self.getBalanceFactor(node.left) < 0:
            node.left = self.rotateLeft(node.left)
            return self.rotateRight(node)
    
        if bf < -1 and self.getBalanceFactor(node.right) <= 0:
            return self.rotateLeft(node)
    
        if bf < -1 and self.getBalanceFactor(node.right) > 0:
            node.right = self.rotateRight(node.right)
            return self.rotateLeft(node)
    
        return node
    
    def getSize(self, node):
        return node.size if node else 0
    
    def getHeight(self, node):
        return node.height if node else 0
    
    def getBalanceFactor(self, node):
        if not node:
            return 0
        return self.getHeight(node.left) - self.getHeight(node.right)
    
    def rotateRight(self, node):
        left = node.left
        left_right = left.right
    
        left.right = node
        node.left = left_right
    
        node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right))
        node.size = 1 + self.getSize(node.left) + self.getSize(node.right)
        left.height = 1 + max(self.getHeight(left.left), self.getHeight(left.right))
        left.size = 1 + self.getSize(left.left) + self.getSize(left.right)
    
        return left
    
    def rotateLeft(self, node):
        right = node.right
        right_left = right.left
    
        right.left = node
        node.right = right_left
    
        node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right))
        node.size = 1 + self.getSize(node.left) + self.getSize(node.right)
        right.height = 1 + max(self.getHeight(right.left), self.getHeight(right.right))
        right.size = 1 + self.getSize(right.left) + self.getSize(right.right)
    
        return right
    
    def inorder(self):
        node = self.root
        stack = []
        res = []
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
    
            node = stack.pop()
            res.append(node.data)
            node = node.right
    
        print(res)
    

    def median(s, x): avlTree = AVLTree() for op, val in zip(s, x): if op == "a": avlTree.insert(val) elif op == "r": avlTree.delete(val)