Merge Two Binary Max Heaps
Last Updated :
05 Jul, 2024
Given two binary max heaps, the task is to merge the given heaps to form a new max heap.
Examples :
Input: a[] = {10, 5, 6, 2}, b[] = {12, 7, 9}
Output: {12, 10, 9, 2, 5, 7, 6}
Merge Two Binary Max HeapsInput: a[] = {2, 5, 1, 9, 12}, b[] = {3, 7, 4, 10}
Output: {12, 10, 7, 9, 5, 3, 1, 4, 2}
[Naive Approach] Merge using extra Max Heap - O((N + M)*log(N + M)) Time and O(N + M) Space:
The property of Max Heap is that the top of any Max Heap is always the largest element. We will use this property to merge the given binary Max Heaps.
To do this:
- Create another Max Heap, and insert the elements of given binary max heaps into this one by one.
- Now repeat above step until all the elements from both given Max Heaps are merged into the third one, ensuring the property of largest element on top (max heapify).
- The third Max Heap will be the required merged Binary Max Heap.
Below is the implementation of the above approach:
C++
// C++ Program to merge two binary max heaps
#include <bits/stdc++.h>
using namespace std;
// function to merge max heaps
vector<int> mergeHeaps(vector<int>& a, vector<int>& b,
int n, int m)
{
// Max Heap to store all the elements
priority_queue<int> maxHeap;
// Insert all the elements of first array
for (int i = 0; i < n; i++) {
maxHeap.push(a[i]);
}
// Insert all the elements of second array
for (int i = 0; i < m; i++) {
maxHeap.push(b[i]);
}
vector<int> merged;
// Push all the elements from the max heap
while (!maxHeap.empty()) {
merged.push_back(maxHeap.top());
maxHeap.pop();
}
return merged;
}
int main()
{
// Sample Input
vector<int> a = { 10, 5, 6, 2 };
vector<int> b = { 12, 7, 9 };
int n = a.size(), m = b.size();
vector<int> merged = mergeHeaps(a, b, n, m);
for (int i = 0; i < n + m; i++)
cout << merged[i] << " ";
return 0;
}
Java
import java.util.*;
public class GFG {
// Function to merge max heaps
public static int[] mergeHeaps(int[] a, int[] b, int n, int m) {
// Max Heap to store all the elements
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((x, y) -> y - x);
// Insert all the elements for first array
for (int i = 0; i < n; i++) {
maxHeap.add(a[i]);
}
// Insert all the elements for second array
for (int i = 0; i < m; i++) {
maxHeap.add(b[i]);
}
int[] merged = new int[n + m];
int index = 0;
// Push all the elements from the max heap
while (!maxHeap.isEmpty()) {
merged[index++] = maxHeap.poll();
}
return merged;
}
public static void main(String[] args) {
// Sample Input
int[] a = { 10, 5, 6, 2 };
int[] b = { 12, 7, 9 };
int n = a.length;
int m = b.length;
int[] merged = mergeHeaps(a, b, n, m);
for (int i = 0; i < n + m; i++) {
System.out.print(merged[i] + " ");
}
}
}
Python
import heapq
def merge_heaps(a, b):
# Create a max heap by negating the elements
max_heap = []
# Insert all elements of first list into the max heap
for num in a:
heapq.heappush(max_heap, -num)
# Insert all elements of second list into the max heap
for num in b:
heapq.heappush(max_heap, -num)
merged = []
# Extract elements from the max heap
while max_heap:
merged.append(-heapq.heappop(max_heap))
return merged
# Sample Input
a = [10, 5, 6, 2]
b = [12, 7, 9]
merged = merge_heaps(a, b)
for num in merged:
print(num, end=' ')
JavaScript
function mergeHeaps(a, b) {
// Max Heap to store all the elements
let maxHeap = [];
// Insert all the elements of the first array
for (let num of a) {
maxHeap.push(num);
}
// Insert all the elements of the second array
for (let num of b) {
maxHeap.push(num);
}
// Convert array into a max heap
maxHeap.sort((x, y) => y - x);
return maxHeap;
}
// Sample Input
let a = [10, 5, 6, 2];
let b = [12, 7, 9];
let merged = mergeHeaps(a, b);
console.log(merged.join(' '));
Time Complexity: O((N + M)*log(N + M)), where N is the size of a[] and M is the size of b[].
- Since we are fetching one element after the other from given max heaps, the time for this will be O(N + M)
- Now for each element, we are doing max heapify on the third heap. This heapify operation for element of the heap will take O(log N+M) each time
- Therefore the resultant complexity will be O(N+M)*(log (N+M))
Auxiliary Space: O(N + M), which is the size of the resultant merged binary max heap
[Expected Approach] Merge and then Build Heap - O(N + M) Time and O(N + M) Space:
Another approach is that instead of creating a max heap from the start, flatten the given max heap into arrays and merge them. Then max heapify this merged array.
The benefit of doing so, is that, instead of taking O(log N+M) time everytime to apply heapify operation as shown in above approach, this approach will take only O(N+M) time once to build the final heap.
Below is the implementation of the above approach:
C++
// C++ program to merge two max heaps
#include <bits/stdc++.h>
using namespace std;
// Standard heapify function to heapify a
// subtree rooted under idx. It assumes
// that subtrees of node are already heapified.
void maxHeapify(vector<int>& arr, int n, int idx)
{
// Find largest of node and its children
if (idx >= n)
return;
int l = 2 * idx + 1;
int r = 2 * idx + 2;
int max = idx;
if (l < n && arr[l] > arr[idx])
max = l;
if (r < n && arr[r] > arr[max])
max = r;
// Put maximum value at root and
// recur for the child with the
// maximum value
if (max != idx) {
swap(arr[max], arr[idx]);
maxHeapify(arr, n, max);
}
}
// Builds a max heap of given arr[0..n-1]
void buildMaxHeap(vector<int>& arr, int n)
{
// building the heap from first non-leaf
// node by calling max heapify function
for (int i = n / 2 - 1; i >= 0; i--)
maxHeapify(arr, n, i);
}
// Merges max heaps a[] and b[] into merged[]
vector<int> mergeHeaps(vector<int>& a, vector<int>& b,
int n, int m)
{
// Copy elements of a[] and b[] one by one
// to merged[]
vector<int> merged(n + m, 0);
for (int i = 0; i < n; i++)
merged[i] = a[i];
for (int i = 0; i < m; i++)
merged[n + i] = b[i];
// build heap for the modified array of
// size n+m
buildMaxHeap(merged, n + m);
return merged;
}
// Driver's code
int main()
{
// Sample Input
vector<int> a = { 10, 5, 6, 2 };
vector<int> b = { 12, 7, 9 };
int n = a.size();
int m = b.size();
// Function call
vector<int> merged = mergeHeaps(a, b, n, m);
for (int i = 0; i < n + m; i++)
cout << merged[i] << " ";
return 0;
}
Java
// Java Program to merge two max heaps
import java.util.Arrays;
public class MergeMaxHeaps {
// Standard heapify function to heapify a subtree rooted
// under idx. It assumes that subtrees of node are
// already heapified.
public static void maxHeapify(int[] arr, int n, int idx)
{
if (idx >= n)
return;
int l = 2 * idx + 1;
int r = 2 * idx + 2;
int max = idx;
if (l < n && arr[l] > arr[idx])
max = l;
if (r < n && arr[r] > arr[max])
max = r;
if (max != idx) {
int temp = arr[max];
arr[max] = arr[idx];
arr[idx] = temp;
maxHeapify(arr, n, max);
}
}
// Builds a max heap of given arr[0..n-1]
public static void buildMaxHeap(int[] arr, int n)
{
for (int i = n / 2 - 1; i >= 0; i--) {
maxHeapify(arr, n, i);
}
}
// Merges max heaps a[] and b[] into merged[]
public static int[] mergeHeaps(int[] a, int[] b, int n,
int m)
{
// Merge both the arrays
int[] merged = new int[n + m];
for (int i = 0; i < n; i++)
merged[i] = a[i];
for (int i = 0; i < m; i++)
merged[n + i] = b[i];
buildMaxHeap(merged, n + m);
return merged;
}
public static void main(String[] args)
{
// Sample Input
int[] a = { 10, 5, 6, 2 };
int[] b = { 12, 7, 9 };
int n = a.length;
int m = b.length;
// Function call
int[] merged = mergeHeaps(a, b, n, m);
for (int i = 0; i < n + m; i++)
System.out.print(merged[i] + " ");
}
}
Python
# Python3 program to merge two Max heaps
# Standard heapify function to heapify a subtree
# rooted under idx. It assumes that subtrees of node
# are already heapified
def maxHeapify(arr, n, idx):
if idx >= n:
return
l = 2 * idx + 1
r = 2 * idx + 2
max_idx = idx
if l < n and arr[l] > arr[max_idx]:
max_idx = l
if r < n and arr[r] > arr[max_idx]:
max_idx = r
if max_idx != idx:
arr[max_idx], arr[idx] = arr[idx], arr[max_idx]
maxHeapify(arr, n, max_idx)
# Builds a max heap of given arr[0..n-1]
def buildMaxHeap(arr, n):
for i in range(n // 2 - 1, -1, -1):
maxHeapify(arr, n, i)
# Merges max heaps a[] and b[] into merged[]
def mergeHeaps(a, b, n, m):
merged = a + b
l = len(merged)
buildMaxHeap(merged, l)
return merged
# Sample Input
a = [10, 5, 6, 2]
b = [12, 7, 9]
# Function call
merged = mergeHeaps(a, b, len(a), len(b))
for x in merged:
print(x, end = " ")
C#
// C# program to merge two max heaps
using System;
using System.Collections.Generic;
public class GFG {
// Standard heapify function to heapify a subtree rooted
// under idx. It assumes that subtrees of node are
// already heapified.
public static void MaxHeapify(List<int> arr, int n,
int idx)
{
if (idx >= n)
return;
int l = 2 * idx + 1;
int r = 2 * idx + 2;
int max = idx;
if (l < n && arr[l] > arr[max])
max = l;
if (r < n && arr[r] > arr[max])
max = r;
if (max != idx) {
int temp = arr[max];
arr[max] = arr[idx];
arr[idx] = temp;
MaxHeapify(arr, n, max);
}
}
// Builds a max heap of given arr[0..n-1]
public static void BuildMaxHeap(List<int> arr, int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
MaxHeapify(arr, n, i);
}
// Merges max heaps a[] and b[] into merged[]
public static List<int>
MergeHeaps(List<int> a, List<int> b, int n, int m)
{
List<int> merged = new List<int>(n + m);
for (int i = 0; i < n; i++)
merged.Add(a[i]);
for (int i = 0; i < m; i++)
merged.Add(b[i]);
BuildMaxHeap(merged, n + m);
return merged;
}
public static void Main()
{
// Sample Input
List<int> a = new List<int>{ 10, 5, 6, 2 };
List<int> b = new List<int>{ 12, 7, 9 };
int n = a.Count;
int m = b.Count;
// Function call
List<int> merged = MergeHeaps(a, b, n, m);
foreach(int num in merged) Console.Write(num + " ");
}
}
JavaScript
// Javascript program to merge two max heaps.
// Standard heapify function to heapify a
// subtree rooted under idx. It assumes
// that subtrees of node are already heapified.
function maxHeapify(arr, n, idx) {
if (idx >= n) return;
let l = 2 * idx + 1;
let r = 2 * idx + 2;
let max = idx;
if (l < n && arr[l] > arr[idx]) max = l;
if (r < n && arr[r] > arr[max]) max = r;
if (max !== idx) {
[arr[max], arr[idx]] = [arr[idx], arr[max]];
maxHeapify(arr, n, max);
}
}
// Builds a max heap of given arr[0..n-1]
function buildMaxHeap(arr, n) {
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
maxHeapify(arr, n, i);
}
}
// Merges max heaps a[] and b[] into merged[]
function mergeHeaps(a, b) {
let n = a.length;
let m = b.length;
let merged = new Array(n + m);
for (let i = 0; i < n; i++) merged[i] = a[i];
for (let i = 0; i < m; i++) merged[n + i] = b[i];
buildMaxHeap(merged, n + m);
return merged;
}
// Driver's code
// Sample Input
let a = [10, 5, 6, 2];
let b = [12, 7, 9];
// Function call
let merged = mergeHeaps(a, b);
for (let i = 0; i < merged.length; i++) {
console.log(merged[i] + " ");
}
Time Complexity: O(N + M)
Auxiliary Space: O(N + M)
Time Complexity: O(N + M), where N is the size of a[] and M is the size of b[].
- Time taken to flatten first binary heap is O(N), which is already provided as input
- Time taken to flatten second binary heap is O(M), which is already provided as input
- Time for merging two arrays = O(N+M)
- Time to build max heap from merged array = O(N+M)
- Therefore the resultant complexity will be O(N+M)
Auxiliary Space: O(N + M), which is the size of the resultant merged binary max heap
Similar Reads
Heap Data Structure A Heap is a complete binary tree data structure that satisfies the heap property: for every node, the value of its children is greater than or equal to its own value. Heaps are usually used to implement priority queues, where the smallest (or largest) element is always at the root of the tree.Basics
2 min read
Introduction to Heap - Data Structure and Algorithm Tutorials A Heap is a special tree-based data structure with the following properties:It is a complete binary tree (all levels are fully filled except possibly the last, which is filled from left to right).It satisfies either the max-heap property (every parent node is greater than or equal to its children) o
15+ min read
Binary Heap A Binary Heap is a complete binary tree that stores data efficiently, allowing quick access to the maximum or minimum element, depending on the type of heap. It can either be a Min Heap or a Max Heap. In a Min Heap, the key at the root must be the smallest among all the keys in the heap, and this pr
13 min read
Advantages and Disadvantages of Heap Advantages of Heap Data StructureTime Efficient: Heaps have an average time complexity of O(log n) for inserting and deleting elements, making them efficient for large datasets. We can convert any array to a heap in O(n) time. The most important thing is, we can get the min or max in O(1) timeSpace
2 min read
Time Complexity of building a heap Consider the following algorithm for building a Heap of an input array A. A quick look over the above implementation suggests that the running time is O(n * lg(n)) since each call to Heapify costs O(lg(n)) and Build-Heap makes O(n) such calls. This upper bound, though correct, is not asymptotically
2 min read
Applications of Heap Data Structure Heap Data Structure is generally taught with Heapsort. Heapsort algorithm has limited uses because Quicksort is better in practice. Nevertheless, the Heap data structure itself is enormously used. Priority Queues: Heaps are commonly used to implement priority queues, where elements with higher prior
2 min read
Comparison between Heap and Tree What is Heap? A Heap is a special Tree-based data structure in which the tree is a complete binary tree. Types of Heap Data Structure: Generally, Heaps can be of two types: Max-Heap: In a Max-Heap the key present at the root node must be greatest among the keys present at all of its children. The sa
3 min read
When building a Heap, is the structure of Heap unique? What is Heap? A heap is a tree based data structure where the tree is a complete binary tree that maintains the property that either the children of a node are less than itself (max heap) or the children are greater than the node (min heap). Properties of Heap: Structural Property: This property sta
4 min read
Some other type of Heap
Easy problems on Heap
Check if a given Binary Tree is a HeapGiven a binary tree, check if it has heap property or not, Binary tree needs to fulfil the following two conditions for being a heap: It should be a complete tree (i.e. Every level of the tree, except possibly the last, is completely filled, and all nodes are as far left as possible.).Every nodeâs v
15+ min read
How to check if a given array represents a Binary Heap?Given an array, how to check if the given array represents a Binary Max-Heap.Examples: Input: arr[] = {90, 15, 10, 7, 12, 2} Output: True The given array represents below tree 90 / \ 15 10 / \ / 7 12 2 The tree follows max-heap property as every node is greater than all of its descendants. Input: ar
11 min read
Iterative HeapSortHeapSort is a comparison-based sorting technique where we first build Max Heap and then swap the root element with the last element (size times) and maintains the heap property each time to finally make it sorted. Examples: Input : 10 20 15 17 9 21 Output : 9 10 15 17 20 21 Input: 12 11 13 5 6 7 15
11 min read
Find k largest elements in an arrayGiven an array arr[] and an integer k, the task is to find k largest elements in the given array. Elements in the output array should be in decreasing order.Examples:Input: [1, 23, 12, 9, 30, 2, 50], k = 3Output: [50, 30, 23]Input: [11, 5, 12, 9, 44, 17, 2], k = 2Output: [44, 17]Table of Content[Nai
15+ min read
Kâth Smallest Element in Unsorted ArrayGiven an array arr[] of N distinct elements and a number K, where K is smaller than the size of the array. Find the K'th smallest element in the given array. Examples:Input: arr[] = {7, 10, 4, 3, 20, 15}, K = 3 Output: 7Input: arr[] = {7, 10, 4, 3, 20, 15}, K = 4 Output: 10 Table of Content[Naive Ap
15 min read
Height of a complete binary tree (or Heap) with N nodesConsider a Binary Heap of size N. We need to find the height of it. Examples: Input : N = 6 Output : 2 () / \ () () / \ / () () () Input : N = 9 Output : 3 () / \ () () / \ / \ () () () () / \ () ()Recommended PracticeHeight of HeapTry It! Let the size of the heap be N and the height be h. If we tak
3 min read
Heap Sort for decreasing order using min heapGiven an array of elements, sort the array in decreasing order using min heap. Examples: Input : arr[] = {5, 3, 10, 1}Output : arr[] = {10, 5, 3, 1}Input : arr[] = {1, 50, 100, 25}Output : arr[] = {100, 50, 25, 1}Prerequisite: Heap sort using min heap.Using Min Heap Implementation - O(n Log n) Time
11 min read