Assignment 6.1: The AVL Tree (5 points)
The following Python code implements the AVL tree which can do single and double rotations to the right. Finalize the class AVL by creating following methods:
- left_rotation(root: AVLNode): symmetrical to
right_rotation
- right_left_rotation(root: AVLNode): symmetrical to left_right_rotation
- preorder(): enumerates the keys and their balance values in preorder
- the format: 'key1:balance1 key2:balance2 key3:balance3'
Finally, finalize the method insert_help so that it functions properly.
Submit your solution in CodeGrade as AVL.py.
An example program:
if __name__ == "__main__":
Tree = AVL()
for key in [9, 10, 11, 3, 2, 6, 4, 7, 5, 1]:
Tree.insert(key)
Tree.preorder() # 9;-1 4;0 2;0 1;0 3;0 6;0 5;0 7;0 10;1 11;0
A code template for the AVL tree:
class AVLNode:
# Constructor for new node
def __init__(self, key: int):
self.key = key
self.left = None
self.right = None
self.balance = 0
class AVL:
# Constructor for new AVL
def __init__(self):
self.root = None
self.is_balanced = True
# Inserts a new key to the search tree
def insert(self, key):
self.root = self.insert_help(self.root, key)
# Help function for insert
def insert_help(self, root, key):
if not root:
root = AVLNode(key)
self.is_balanced = False
elif key < root.key:
root.left = self.insert_help(root.left, key)
if not self.is_balanced: # Check for possible rotations
if root.balance >= 0: # No Rotations needed, update balance variables
self.is_balanced = root.balance == 1
root.balance -= 1
else: # Rotation(s) needed
if root.left.balance == -1:
root = self.right_rotation(root) # Single rotation
else:
root = self.left_right_rotation(root) # Double rotation
self.is_balanced = True
elif key > root.key:
root.right = self.insert_help(root.right, key)
# TODO
return root
# Single rotation: right rotation around root
def right_rotation(self, root):
child = root.left # Set variable for child node
root.left = child.right # Rotate
child.right = root
child.balance = root.balance = 0 # Fix balance variables
return child
# Single rotation: left rotation around root
def left_rotation(self, root):
# TODO
# Double rotation: left rotation around child node followed by right rotation around root
def left_right_rotation(self, root):
child = root.left
grandchild = child.right # Set variables for child node and grandchild node
child.right = grandchild.left # Rotate
grandchild.left = child
root.left = grandchild.right
grandchild.right = root
root.balance = child.balance = 0 # Fix balance variables
if grandchild.balance == -1:
root.balance = 1
elif grandchild.balance == 1:
child.balance = -1
grandchild.balance = 0
return grandchild
# Double rotation: right rotation around child node followed by left rotation around root
def right_left_rotation(self, root):
# TODO
Assignment 6.2: The Min Heap (3 points)
Implement the min heap structure that stores positive integers in Python. Create class MinHeap which has following functions:
- push(key: int): inserts a new key to the heap while maintaining the min heap property.
- pop(): removes the smallest key from the heap and returns its value.
- print(): prints the heap in breadth-first order
- the format: key values separated by spaces (e.g. 1 2 3 4).
Make sure that the heap always maintains the min heap property. The best practice is to store the heap structure in a list where a key in index \(i\)
- has a left child at index \(2i + 1\)
- has a right child at index \(2i + 2\)
- has its parent at index \(\lfloor \frac{i-1}{2} \rfloor\) (\(\lfloor \ldots \rfloor\) rounds down to the nearest integer)
A code template an example program:
class MinHeap:
# TODO
if __name__ == "__main__":
items = [4, 8, 6, 5, 1, 2, 3]
heap = MinHeap()
[heap.push(key) for key in items]
heap.print() # 1 4 2 8 5 6 3
print(heap.pop()) # 1
heap.print() # 2 4 3 8 5 6
Submit your solution in CodeGrade as minheap.py.