Welcome to our deep dive into the fascinating world of data structures! Today, we're going to explore one of the most efficient and versatile data structures: Binary Heap. By the end of this lesson, you'll be equipped with the knowledge to implement binary heaps in your own projects and solve complex real-world problems. š”
A Binary Heap is a specialized type of binary tree that maintains a nearly sorted property: the parent nodes are always greater than or equal to their child nodes. This property allows binary heaps to provide efficient solutions for various problems, such as finding the kth largest element, sorting arrays, and implementing priority queues. š”
Binary Heap offers several advantages over other data structures:
Efficient Operations: Binary heap provides constant time complexity (O(1)) for operations like insertion and deletion of the root node, and logarithmic time complexity (O(log n)) for finding the minimum/maximum elements and heapify operations.
Practical Applications: Binary heaps are essential in implementing priority queues, Huffman coding, and Dijkstra's algorithm for finding the shortest paths in graphs.
Space Efficiency: Binary heaps require less space than other sorting algorithms, making them suitable for memory-constrained systems.
Binary heaps can be of two types:
Min-Heap: A min-heap is a binary heap where the parent node is always less than or equal to its child nodes. This is particularly useful when the smallest element needs to be accessed frequently.
Max-Heap: A max-heap is a binary heap where the parent node is always greater than or equal to its child nodes. This is useful when the largest element needs to be accessed frequently.
In this lesson, we'll focus on the Max-Heap for simplicity.
Building a max-heap from an unsorted array involves the following steps:
Let's implement a max-heap using Python:
def heapify(arr, n, i):
# Find the largest among root, left child and right child
largest = i
l = 2 * i + 1
r = 2 * i + 2
if l < n and arr[largest] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
# If the root is not in its correct position
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i] # Swap the elements
heapify(arr, n, largest) # Recursively heapify the affected sub-tree
def build_heap(arr):
n = len(arr)
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)To insert an element into a max-heap, we simply add it to the end of the array and call the heapify() function to restore the heap property:
def insert(arr, value):
arr.append(value)
heapify(arr, len(arr), len(arr) - 1)To extract the maximum element from a max-heap, we swap the first and last elements, reduce the size of the array, and heapify the root node:
def extract_max(arr):
if len(arr) <= 1:
return None
max_val = arr[0]
arr[0], arr[-1] = arr[-1], arr[0] # Swap the first and last elements
arr.pop()
heapify(arr, len(arr), 0)
return max_valWhat is a Binary Heap?
That's it for today! In the next lesson, we'll dive deeper into binary heaps and learn how to implement priority queues using our max-heap implementation. Stay tuned! š