Open In App

Max Heap in C++

Last Updated : 12 Jun, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

A max heap is defined as a complete binary tree where every node's value is at least as large as the values of its children. This makes it useful for implementing priority queues, where the highest priority element is always at the root. In this article, we will learn how to implement the max heap data structure in C++.

Implementation of Max Heap in C++

A max heap is a tree-based data structure that satisfies the property of a heap. For every node, i in the max heap other than the root, the value of that node is less than or equal to the value of its parent. Each root node in a max heap can have almost two child nodes where the value of the child nodes must be less than or equal to its parent node. To implement max heap in C++ we use the array data structure. For any node at the index i in the array, the relationship between the parent and child nodes are as follows:

  • Index of Parent Node: (i – 1) / 2
  • Index of the Left child Node: 2 * i + 1
  • Index of the Right child Node: 2 * i + 2

Representation of Max Heap in C++

To represent a max heap efficiently, we can use a class instead of an array because for an array we will have to maintain separate variables to keep track of the size of the heap. Using a class we can encapsulate all of the heap data members and operations within a single class. We will use template instead of a specific data type for the max heap so that it can support multiple types of data. The MaxHeap class will consist of the following data members:

template <typename T>
class MaxHeap {
vector<T> array;
int size;
int capacity;
};

here:

  • array: is a std::vector that will store the max heap elements.
  • size: denotes the current number of elements present in the max heap.
  • capacity: denote the maximum number of elements the max heap can hold.
  • T: denotes the type of data the max heap will hold.

The following diagram represents how the index of each element in a max heap is mapped within the array:

representation-of-max-heap-in-cpp

Explanation: For the above max heap the root node 15 of the max heap is present at the 0th index of the array,and it's left and right child 5 and 10 are present at 2*i+1 and 2*i+2 indices that is at index 1 and 2. Similary the other nodes of the max heap are represented in the array using the same approach.

Basic Operations Implementation of Max Heap in C++

Following are some basic operations that are required to work with max heap in C++:

Operation Name

Description

Time Complexity

Space Complexity

Heapify

Reorganizes the subtree for a given index of the max heap to ensure that the heap property is maintained properly.

O(log n)

O(1)

Insert

Adds a new node to the max heap and ensures that the max heap property is maintained.

O(log n)

O(1)

Delete Key

Removes a specific node from the max heap.

O(log n)

O(1)

Top

Returns the value of the root node of the max heap.

O(1)

O(1)

Pop

Deletes the root node, returns its value, and heapifies the remaining heap

O(log n)

O(1)

BuildHeap

Converts an array into max heap.

O(n)

O(1)

Now let's go through the algorithms for implementing each of these functions for max heap in C++:


Algorithm for Heapify Function

  1. Find the left child and right child using the 2*i+1 and 2*i+2 formula.
  2. Identify the largest among the root, left child, and right child.
  3. If the root node is not the largest, swap it with the child that has the largest value.
  4. Recursively apply heapify to the affected subtree.
  5. Repeat until the heap property is restored.

Algorithm for Inserting a Node

  1. Increase the size of the array by 1 .
  2. Insert the node to insert in the heap at the end of the array.
  3. Initialize i to the index of the newly inserted element.
  4. While i !=root and value of new element greater than it's parent :
    1. Swap the element with it's parent.
    2. Update i to the parent index.

Note: You can find the parent index using (index-1)/2 formula.

Algorithm for Deleting a Node

  1. Traverse the max heap and find the node to you want to delete.
  2. Store the index of this node.
  3. Replace the node with the last node in the max heap.
  4. Decrease the heap size by 1.
  5. Apply heapify function to the affected index to restore the heap property.

Algorithm for the Top Function

  1. Check if the heap is empty.
  2. If not empty, return the root element (maximum element in a max heap).
  3. If empty, return -1.

Algorithm for the Pop Function

  1. Check if the heap is empty. If empty return -1.
  2. Store the root element.
  3. Replace the root element with the last element in the heap array.
  4. Reduce the heap size by 1.
  5. Call the heapify function on the root node to restore the max heap property.
  6. Return the stored root element.

Algorithm for Build Heap Function

  1. Start from the last non-leaf node of the max heap and move towards the root node.
  2. Apply Heapify to each node.
  3. Continue this process for all nodes until the root node.
  4. The max heap will be built when all nodes satisfy the max heap property.

C++ Program for Implementing Max Heap

The following program illustrates how we can implement a max heap using array in C++:

C++
// C++ Program for Implementing Max Heap
#include <iostream>
#include <vector>
#include <climits>

using namespace std;

// Template for MaxHeap
template <typename T>
// Class for MaxHeap
class MaxHeap {
private:
    vector<T> array;  
    int size;
    int capacity;     

public:
    // Constructor to initialize the heap with a given capacity
     MaxHeap(int capacity) {
        this->size = 0;
        this->capacity = capacity;
        this->array.resize(capacity);
    }
    
    // Function to heapify the node at index i
    void heapify(int i) {
        int largest = i;           
        int left = 2 * i + 1;      
        int right = 2 * i + 2;     
        
        if (left < size && array[left] > array[largest])
            largest = left;

        
        if (right < size && array[right] > array[largest])
            largest = right;

        
        if (largest != i) {
            swap(array[i], array[largest]);  
            heapify(largest);               
        }
    }

    // Function to build a max heap from a given array
    void buildHeap(const vector<T>& arr) {
        capacity = arr.size();
        size = capacity;
        array = arr;

        // Build heap (rearrange array)
        for (int i = (size - 1) / 2; i >= 0; i--) {
            heapify(i);
        }
    }

    // Function to insert a new value into the heap
    void insert(T value) {
        if (size == capacity) {
            // Resize the heap if necessary
            capacity *= 2;
            array.resize(capacity);
        }

        size++;
        int i = size - 1;
        array[i] = value;

        // Fix the max heap property if it is violated
        while (i != 0 && array[(i - 1) / 2] < array[i]) {
            swap(array[i], array[(i - 1) / 2]);
            i = (i - 1) / 2;
        }
    }

  // Function to get the value of the root node of the max heap
    T top() {
        if (size <= 0)
        // Indicates that the heap is empty
            return -1; 

        return array[0];
    }

    // Function to remove and return the maximum value from the heap
    T pop() {
        if (size <= 0)
            return -1; 
        if (size == 1) {
            size--;
            return array[0];
        }

        // Store the maximum value, and remove it
        T root = array[0];
        array[0] = array[size - 1];
        size--;
        // Heapify the root node after deletion
        heapify(0);  
        return root;
    }

    // Function to delete a specific key from the heap
    void deleteKey(T key) {
        // Find the index of the key
        int index = -1;
        for (int i = 0; i < size; ++i) {
            if (array[i] == key) {
                index = i;
                break;
            }
        }
        // If key is not found, return
        if (index == -1) {
            cout << "Key not found" << endl;
            return;
        }

        // If the key is found, delete it
        // If it's the last element, simply reduce the size
        if (index == size - 1) {
            size--;
            return;
        }

        // Move the last element to the index of the key to be deleted
        array[index] = array[size - 1];
        size--;

        // Heapify down to maintain heap property
        heapify(index);
    }

    // Function to print the heap
    void print() const {
        cout << "Max Heap: ";
        for (int i = 0; i < size; ++i)
            cout << array[i] << " ";
        cout << endl;
    }
};

int main() {
    // Create a MaxHeap with initial capacity of 6
    MaxHeap<int> maxHeap(6);
    vector<int> arr = {2, 3, 4, 5, 10, 15};

    // Build the heap from the array
    maxHeap.buildHeap(arr);

    // Print the max heap
    maxHeap.print();

    // Insert a node into the heap
    maxHeap.insert(9);
    cout << "After inserting 9: " << endl;
    maxHeap.print();

    // Get the maximum value from the max heap
    cout << "Top value: " << maxHeap.top() << endl;

    // Delete the root node of the max heap
    cout << "Popped value: " << maxHeap.pop() << endl;
    cout << "After popping: ";
    maxHeap.print();

    // Delete a specific value from the max heap
    maxHeap.deleteKey(5);
    cout << "After deleting the node 5: ";
    maxHeap.print();

    return 0;
}

Output
Max Heap: 15 10 4 5 3 2 
After inserting 9: 
Max Heap: 15 10 9 5 3 2 4 
Top value: 15
Popped value: 15
After popping: Max Heap: 10 5 9 4 3 2 
After deleting the node 5: Max Heap: 10 4 9 2 3 

Related Articles

You can also read the following articles to improve your understanding about the heap data structure:



Next Article
Article Tags :
Practice Tags :

Similar Reads