[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>usingnamespacestd;// function to merge max heapsvector<int>mergeHeaps(vector<int>&a,vector<int>&b,intn,intm){// Max Heap to store all the elementspriority_queue<int>maxHeap;// Insert all the elements of first arrayfor(inti=0;i<n;i++){maxHeap.push(a[i]);}// Insert all the elements of second arrayfor(inti=0;i<m;i++){maxHeap.push(b[i]);}vector<int>merged;// Push all the elements from the max heapwhile(!maxHeap.empty()){merged.push_back(maxHeap.top());maxHeap.pop();}returnmerged;}intmain(){// Sample Inputvector<int>a={10,5,6,2};vector<int>b={12,7,9};intn=a.size(),m=b.size();vector<int>merged=mergeHeaps(a,b,n,m);for(inti=0;i<n+m;i++)cout<<merged[i]<<" ";return0;}
Java
importjava.util.*;publicclassGFG{// Function to merge max heapspublicstaticint[]mergeHeaps(int[]a,int[]b,intn,intm){// Max Heap to store all the elementsPriorityQueue<Integer>maxHeap=newPriorityQueue<>((x,y)->y-x);// Insert all the elements for first arrayfor(inti=0;i<n;i++){maxHeap.add(a[i]);}// Insert all the elements for second arrayfor(inti=0;i<m;i++){maxHeap.add(b[i]);}int[]merged=newint[n+m];intindex=0;// Push all the elements from the max heapwhile(!maxHeap.isEmpty()){merged[index++]=maxHeap.poll();}returnmerged;}publicstaticvoidmain(String[]args){// Sample Inputint[]a={10,5,6,2};int[]b={12,7,9};intn=a.length;intm=b.length;int[]merged=mergeHeaps(a,b,n,m);for(inti=0;i<n+m;i++){System.out.print(merged[i]+" ");}}}
Python
importheapqdefmerge_heaps(a,b):# Create a max heap by negating the elementsmax_heap=[]# Insert all elements of first list into the max heapfornumina:heapq.heappush(max_heap,-num)# Insert all elements of second list into the max heapfornuminb:heapq.heappush(max_heap,-num)merged=[]# Extract elements from the max heapwhilemax_heap:merged.append(-heapq.heappop(max_heap))returnmerged# Sample Inputa=[10,5,6,2]b=[12,7,9]merged=merge_heaps(a,b)fornuminmerged:print(num,end=' ')
JavaScript
functionmergeHeaps(a,b){// Max Heap to store all the elementsletmaxHeap=[];// Insert all the elements of the first arrayfor(letnumofa){maxHeap.push(num);}// Insert all the elements of the second arrayfor(letnumofb){maxHeap.push(num);}// Convert array into a max heapmaxHeap.sort((x,y)=>y-x);returnmaxHeap;}// Sample Inputleta=[10,5,6,2];letb=[12,7,9];letmerged=mergeHeaps(a,b);console.log(merged.join(' '));
Output
12 10 9 7 6 5 2
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>usingnamespacestd;// Standard heapify function to heapify a// subtree rooted under idx. It assumes// that subtrees of node are already heapified.voidmaxHeapify(vector<int>&arr,intn,intidx){// Find largest of node and its childrenif(idx>=n)return;intl=2*idx+1;intr=2*idx+2;intmax=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 valueif(max!=idx){swap(arr[max],arr[idx]);maxHeapify(arr,n,max);}}// Builds a max heap of given arr[0..n-1]voidbuildMaxHeap(vector<int>&arr,intn){// building the heap from first non-leaf// node by calling max heapify functionfor(inti=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,intn,intm){// Copy elements of a[] and b[] one by one// to merged[]vector<int>merged(n+m,0);for(inti=0;i<n;i++)merged[i]=a[i];for(inti=0;i<m;i++)merged[n+i]=b[i];// build heap for the modified array of// size n+mbuildMaxHeap(merged,n+m);returnmerged;}// Driver's codeintmain(){// Sample Inputvector<int>a={10,5,6,2};vector<int>b={12,7,9};intn=a.size();intm=b.size();// Function callvector<int>merged=mergeHeaps(a,b,n,m);for(inti=0;i<n+m;i++)cout<<merged[i]<<" ";return0;}
Java
// Java Program to merge two max heapsimportjava.util.Arrays;publicclassMergeMaxHeaps{// Standard heapify function to heapify a subtree rooted// under idx. It assumes that subtrees of node are// already heapified.publicstaticvoidmaxHeapify(int[]arr,intn,intidx){if(idx>=n)return;intl=2*idx+1;intr=2*idx+2;intmax=idx;if(l<n&&arr[l]>arr[idx])max=l;if(r<n&&arr[r]>arr[max])max=r;if(max!=idx){inttemp=arr[max];arr[max]=arr[idx];arr[idx]=temp;maxHeapify(arr,n,max);}}// Builds a max heap of given arr[0..n-1]publicstaticvoidbuildMaxHeap(int[]arr,intn){for(inti=n/2-1;i>=0;i--){maxHeapify(arr,n,i);}}// Merges max heaps a[] and b[] into merged[]publicstaticint[]mergeHeaps(int[]a,int[]b,intn,intm){// Merge both the arraysint[]merged=newint[n+m];for(inti=0;i<n;i++)merged[i]=a[i];for(inti=0;i<m;i++)merged[n+i]=b[i];buildMaxHeap(merged,n+m);returnmerged;}publicstaticvoidmain(String[]args){// Sample Inputint[]a={10,5,6,2};int[]b={12,7,9};intn=a.length;intm=b.length;// Function callint[]merged=mergeHeaps(a,b,n,m);for(inti=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 heapifieddefmaxHeapify(arr,n,idx):ifidx>=n:returnl=2*idx+1r=2*idx+2max_idx=idxifl<nandarr[l]>arr[max_idx]:max_idx=lifr<nandarr[r]>arr[max_idx]:max_idx=rifmax_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]defbuildMaxHeap(arr,n):foriinrange(n//2-1,-1,-1):maxHeapify(arr,n,i)# Merges max heaps a[] and b[] into merged[]defmergeHeaps(a,b,n,m):merged=a+bl=len(merged)buildMaxHeap(merged,l)returnmerged# Sample Inputa=[10,5,6,2]b=[12,7,9]# Function callmerged=mergeHeaps(a,b,len(a),len(b))forxinmerged:print(x,end=" ")
C#
// C# program to merge two max heapsusingSystem;usingSystem.Collections.Generic;publicclassGFG{// Standard heapify function to heapify a subtree rooted// under idx. It assumes that subtrees of node are// already heapified.publicstaticvoidMaxHeapify(List<int>arr,intn,intidx){if(idx>=n)return;intl=2*idx+1;intr=2*idx+2;intmax=idx;if(l<n&&arr[l]>arr[max])max=l;if(r<n&&arr[r]>arr[max])max=r;if(max!=idx){inttemp=arr[max];arr[max]=arr[idx];arr[idx]=temp;MaxHeapify(arr,n,max);}}// Builds a max heap of given arr[0..n-1]publicstaticvoidBuildMaxHeap(List<int>arr,intn){for(inti=n/2-1;i>=0;i--)MaxHeapify(arr,n,i);}// Merges max heaps a[] and b[] into merged[]publicstaticList<int>MergeHeaps(List<int>a,List<int>b,intn,intm){List<int>merged=newList<int>(n+m);for(inti=0;i<n;i++)merged.Add(a[i]);for(inti=0;i<m;i++)merged.Add(b[i]);BuildMaxHeap(merged,n+m);returnmerged;}publicstaticvoidMain(){// Sample InputList<int>a=newList<int>{10,5,6,2};List<int>b=newList<int>{12,7,9};intn=a.Count;intm=b.Count;// Function callList<int>merged=MergeHeaps(a,b,n,m);foreach(intnuminmerged)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.functionmaxHeapify(arr,n,idx){if(idx>=n)return;letl=2*idx+1;letr=2*idx+2;letmax=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]functionbuildMaxHeap(arr,n){for(leti=Math.floor(n/2)-1;i>=0;i--){maxHeapify(arr,n,i);}}// Merges max heaps a[] and b[] into merged[]functionmergeHeaps(a,b){letn=a.length;letm=b.length;letmerged=newArray(n+m);for(leti=0;i<n;i++)merged[i]=a[i];for(leti=0;i<m;i++)merged[n+i]=b[i];buildMaxHeap(merged,n+m);returnmerged;}// Driver's code// Sample Inputleta=[10,5,6,2];letb=[12,7,9];// Function callletmerged=mergeHeaps(a,b);for(leti=0;i<merged.length;i++){console.log(merged[i]+" ");}
Output
12 10 9 2 5 7 6
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