C++ Program to Implement Min Heap



In this article, we will write a C++ program that implements a Min Heap. A Min Heap is a binary tree where the value of each node is less than or equal to the values of its children. We will explain how to create a Min Heap using arrays and implement operations like insertion and deletion. The article will cover the following topics:

What is a Heap?

A heap is a tree-based data structure that follows a specific rule called the heap property. It is always a complete binary tree, meaning all levels are fully filled, except possibly the last one, which is filled from left to right.

Types of Heap

Heaps can be classified into two types based on their properties:

  • Max Heap: In a max heap, the value of each parent node is greater than or equal to the values of its children. This ensures that the largest element is always at the root.
  • Min Heap: In a min heap, the value of each parent node is less than or equal to the values of its children. This ensures that the smallest element is always at the root.
types of heap

Representing a Heap

Before we look at heap operations, let's understand how heaps can be represented. A common way is by using arrays. Since heaps form complete binary trees, there is no wasted space.

For example, the max heap with elements (30, 20, 15, 5, 10, 12, 6) can be represented as an array.

Declaring a Heap: To declare a heap, we use this structure:

struct Heap {
    int *array;    // Array to store heap elements
    int count;     // Number of elements in the heap
    int capacity;  // Size of the heap
    int heap_type; // Type of heap (Min or Max)
};

Creating a Heap:To create a heap, we use a function that allocates memory for the heap structure and the array of elements. Here's how it we can create a heap:

struct Heap* CreateHeap(int capacity, int heap_type) {
    // Allocate memory for the heap structure
    struct Heap* h = (struct Heap*)malloc(sizeof(struct Heap));
    if (h == NULL) {  // Check if memory allocation for heap failed
        printf("Memory Error");
        return NULL;
    }

    // Initialize heap properties
    h->heap_type = heap_type;  // Set heap type (Min or Max)
    h->count = 0;              // Set the initial count of elements to 0
    h->capacity = capacity;    // Set the maximum capacity of the heap
    h->array = (int*)malloc(sizeof(int) * h->capacity);  // Allocate memory for the heap array

    if (h->array == NULL) {  // Check if memory allocation for the array failed
        printf("Memory Error");
        return NULL;
    }

    return h;  // Return the created heap
}   

Time Complexity: The time complexity of creating a heap is O(1).

What is Min Heap?

A Min Heap is a complete binary tree where each parent node has a value smaller than or equal to its children, ensuring that the smallest element is always at the root.

Key points about Min Heap:

  • The root node contains the smallest element.
  • It is a complete binary tree, with all levels fully filled except possibly the last, and nodes are filled from left to right.
  • For any node at index i, the left child is at index 2i + 1 and the right child is at index 2i + 2.
Min heap visualization

What is Heapify?

Heapify is the process used to maintain the heap property in a binary heap. When a new element is added to the heap, it might not satisfy the heap property. In such cases, heapify helps to fix this by adjusting the heap structure.

For example, in a max-heap, the parent node should always be greater than or equal to its children. If a parent node is smaller than its child, heapify swaps them. This process repeats until the heap property is restored.

Example of Heapify

Consider the following heap before heapifying:

heapify first part

In this heap, the heap property is violated because element 1 is smaller than its parent 31. Additionally, 1 is not in the correct position according to the heap property. To fix this, we start heapifying from element 1, comparing it with its children and moving it down the tree until the heap property is restored.

Heapify Process:

  • Start with element 1. Compare it with its children, 9 and 10. Since 1 is smaller than both, we swap it with the larger child, which is 10:
  • heapify first part
  • Next, compare element 1 with its new children, 8 and 7. We swap 1 with the larger child, 8:
  • heapify first part
  • Now, the heap property is satisfied, as each parent is greater than or equal to its children.
This process, where we move from top to bottom adjusting the elements, is called percolating down.

Min Heap Implementation

We represent the Min Heap using an array. The parent-child relationships are as follows:

  • The parent of a node at index i is at index (i - 1) / 2.
  • The left child of a node at index i is at index 2 * i + 1.
  • The right child of a node at index i is at index 2 * i + 2.

Min Heap Insert Operation

When we insert a new element, we place it at the end of the array. Then, we "heapify" it upwards to maintain the heap property. If the new element is smaller than its parent, we swap them. This continues until the heap property is satisfied.

Steps for Insertion:

  • We add the new element at the end of the heap.
  • We heapify the element by comparing it with its parent and swapping if needed.
  • We repeat this process until the element is in the correct position or reaches the root.
Implementaion of Min Heap

Example

Here's the complete C++ code to implement a Min Heap, where we use a MinHeap class with a vector to store elements. The insert function adds a new element and places it in the correct position, while the heapify function maintains the heap property by swapping elements as needed. The display function shows the heap's current state.

#include <iostream>
#include <vector>
using namespace std;

class MinHeap {
private:
    vector<int> heap;

    // Function to heapify the tree
    void heapify(int index) {
        int left = 2 * index + 1;  // Left child index
        int right = 2 * index + 2; // Right child index
        int smallest = index;

        // If left child is smaller than root
        if (left < heap.size() && heap[left] < heap[smallest]) {
            smallest = left;
        }

        // If right child is smaller than the smallest so far
        if (right < heap.size() && heap[right] < heap[smallest]) {
            smallest = right;
        }

        // If the smallest is not the root
        if (smallest != index) {
            swap(heap[index], heap[smallest]);
            heapify(smallest); // Recursively heapify the affected sub-tree
        }
    }

public:
    // Function to insert an element into the heap
    void insert(int value) {
        // Step 1: Add the new element at the end of the heap
        heap.push_back(value);
        
        // Step 2: Get the index of the newly added element
        int index = heap.size() - 1;
        
        // Step 3: Move the element up to its correct position in the heap
        while (index != 0 && heap[(index - 1) / 2] > heap[index]) {
            // Swap with the parent if current node is smaller
            swap(heap[index], heap[(index - 1) / 2]);
            index = (index - 1) / 2; // Move to the parent's index
        }
    }

    // Function to display the heap
    void display() {
        for (int i = 0; i < heap.size(); ++i) {
            cout << heap[i] << " "; // Print each element in the heap
        }
        cout << endl;
    }
};

int main() {
    MinHeap minHeap;

    // Insert elements into the heap
    minHeap.insert(6);  // Inserting 10 into the heap
     minHeap.display(); 
    minHeap.insert(4);  // Inserting 20 into the heap
     minHeap.display(); 
    minHeap.insert(9);   // Inserting 5 into the heap
     minHeap.display(); 
    minHeap.insert(3);  // Inserting 30 into the heap
     minHeap.display(); 
    minHeap.insert(2);  // Inserting 15 into the heap
    
    // Display the heap after insertions
    cout << "Min Heap after insertions: ";
    minHeap.display();  // Print the final Min Heap

    return 0;
}

Below is the output showing the state of the Min Heap after each insertion, followed by the final heap after all insertions are complete:

6 
4 6 
4 6 9 
3 4 9 6 
Min Heap after insertions: 2 3 9 6 4 

Time Complexity: O(log n), due to the heapify-up process.

Space Complexity: O(n), because we store the elements in the heap array.

Deletion from Min Heap (Extract Min)

To delete an element from the Min Heap, we simply remove the root (smallest element). After removing the root, we replace it with the last element in the heap and remove the last element. Finally, we heapify the tree to restore the heap property.

Steps for Extract Min:

  • We remove the root(smallest element).
  • We replace the root with the last element and remove the last element.
  • We heapify the tree by starting from the root, comparing it with its children, and swapping it with the smaller child if needed. We continue this until the heap property is restored.
Deletion from min heap Process Deletion from min heap Process

Example

Here's a complete C++ code for the deletion operation in Min Heap, where we first insert elements. Then, to delete the root (smallest element), we replace it with the last element in the heap and remove the last element. Finally, we heapify the tree starting from the root to restore the Min Heap property.

#include <iostream>
#include <vector>
using namespace std;

class MinHeap {
private:
    vector<int> heap;

    // Function to heapify the tree to maintain the Min Heap property
    void heapify(int index) {
        int left = 2 * index + 1;  // Left child index
        int right = 2 * index + 2; // Right child index
        int smallest = index;

        // If left child is smaller than root
        if (left < heap.size() && heap[left] < heap[smallest]) {
            smallest = left;
        }

        // If right child is smaller than the smallest so far
        if (right < heap.size() && heap[right] < heap[smallest]) {
            smallest = right;
        }

        // If the smallest is not the root
        if (smallest != index) {
            swap(heap[index], heap[smallest]);
            heapify(smallest); // Recursively heapify the affected sub-tree
        }
    }

public:
    // Function to insert an element into the heap
    void insert(int value) {
        heap.push_back(value);  // Step 1: Add the new element at the end
        
        int index = heap.size() - 1; // Get the index of the newly added element
        
        // Step 2: Move the element up to its correct position in the heap
        while (index != 0 && heap[(index - 1) / 2] > heap[index]) {
            // Swap with the parent if current node is smaller
            swap(heap[index], heap[(index - 1) / 2]);
            index = (index - 1) / 2; // Move to the parent's index
        }
    }

    // Function to extract the minimum element (root) from the heap
    int extractMin() {
        if (heap.empty()) return -1; // Heap is empty, return -1 as an error value
        
        int min = heap[0]; // Root element (smallest element)
        heap[0] = heap.back(); // Replace the root with the last element in the heap
        heap.pop_back(); // Remove the last element
        
        // Heapify the root to restore the heap property
        heapify(0);
        
        return min; // Return the smallest element that was removed
    }

    // Function to display the heap
    void display() {
        for (int i = 0; i < heap.size(); ++i) {
            cout << heap[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    MinHeap minHeap;

    // Insert elements into the heap
    minHeap.insert(6);  // Inserting 10 into the heap
    minHeap.insert(4);  // Inserting 20 into the heap
    minHeap.insert(9);   // Inserting 5 into the heap
    minHeap.insert(3);  // Inserting 30 into the heap
    minHeap.insert(2);  // Inserting 15 into the heap

    cout << "Min Heap after insertions: ";
    minHeap.display();  // Display the heap after insertions
    
    // Perform Extract Min operation (remove the smallest element)
    cout << "Extracted Min: " << minHeap.extractMin() << endl;

    // Display the heap after Extract Min
    cout << "Min Heap after Extract Min: ";
    minHeap.display();  // Display the heap after removal of the root element
    return 0;
}

Here's the output from the code, showing the Min Heap after inserting elements and after removing the smallest element:

Min Heap after insertions: 2 3 9 6 4 
Extracted Min: 2
Min Heap after Extract Min: 3 4 9 6 

Time Complexity: O(log n), because we need to heapify the tree after removal.

Space Complexity: O(1), as no extra space is needed for heapifying.

Conclusion

In this article, we have successfully implemented a Min Heap in C++ by covering key concepts such as insertion, deletion, and heapifying. We also looked at how to keep the heap property intact, making sure the smallest element stays at the root. By using arrays to represent the heap, we performed the operations effectively and showed how to manage a Min Heap.

Updated on: 2025-03-03T13:16:55+05:30

11K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements