A Min-Heap is a Data Structure with the following properties.
- It is a complete Complete Binary Tree.
- The value of the root node must be the smallest among all its descendant nodes and the same thing must be done for its left and right sub-tree also.
Internal Implementation of Min-Heap Data Structure
A heap can be efficiently represented using an array.
- If a node is stored at index i:
- Its left child is at index 2*i + 1.
- Its right child is at index 2*i + 2.
- The parent of a node at index i can be found at index [(i-1)/2].
Operations on Min-heap Data Structure and their Implementation:
Here are some common operations that can be performed on a Heap Data Structure,
Insertion - O(log n) Time and O(n) Space
The insertion operation in a min-heap involves the following steps:
- Add the new element to the end of the heap, in the next available position in the last level of the tree.
- Compare the new element with its parent. If the parent is greater than the new element, swap them.
- Repeat step 2 until the parent is smaller than or equal to the new element, or until the new element reaches the root of the tree.
Illustration:
Suppose the Heap is a Min-Heap as:
C++
#include <iostream>
#include <vector>
using namespace std;
void insert(vector<int>& heap, int value)
{
// Add the new element to the end of the heap
heap.push_back(value);
// Get the index of the last element
int index = heap.size() - 1;
// Compare the new element with
//its parent and swap if necessary
while (index > 0
&& heap[(index - 1) / 2] > heap[index]) {
swap(heap[index], heap[(index - 1) / 2]);
// Move up the tree to the
//parent of the current element
index = (index - 1) / 2;
}
}
int main()
{
vector<int>arr;
vector<int>values = {10, 3, 2, 4, 5, 1};
int n = values.size();
for (int i = 0; i < n; i++) {
insert(arr, values[i]);
cout << "Inserted " << values[i]
<< " into the min-heap: ";
for (int j = 0; j <arr.size(); j++) {
cout << arr[j] << " ";
}
cout << endl;
}
return 0;
}
Java
import java.util.ArrayList;
public class GFG {
public static void insert(ArrayList<Integer> heap, int value) {
// Add the new element to the end of the heap
heap.add(value);
// Get the index of the last element
int index = heap.size() - 1;
// Compare the new element with
// its parent and swap if necessary
while (index > 0 && heap.get((index - 1) / 2) > heap.get(index)) {
int temp = heap.get(index);
heap.set(index, heap.get((index - 1) / 2));
heap.set((index - 1) / 2, temp);
// Move up the tree to the
// parent of the current element
index = (index - 1) / 2;
}
}
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
int[] values = {10, 3, 2, 4, 5, 1};
int n = values.length;
for (int i = 0; i < n; i++) {
insert(arr, values[i]);
System.out.print("Inserted " + values[i] + " into the min-heap: ");
for (int j = 0; j < arr.size(); j++) {
System.out.print(arr.get(j) + " ");
}
System.out.println();
}
}
}
Python
def insert(heap, value):
# Add the new element to the end of the heap
heap.append(value)
# Get the index of the last element
index = len(heap) - 1
# Compare the new element with
# its parent and swap if necessary
while index > 0 and heap[(index - 1) // 2] > heap[index]:
heap[index], heap[(index - 1) // 2] = heap[(index - 1) // 2], heap[index]
# Move up the tree to the
# parent of the current element
index = (index - 1) // 2
if __name__ == "__main__":
arr = []
values = [10, 3, 2, 4, 5, 1]
n = len(values)
for i in range(n):
insert(arr, values[i])
print(f"Inserted {values[i]} into the min-heap: ", end="")
for j in range(len(arr)):
print(arr[j], end=" ")
print()
C#
using System;
using System.Collections.Generic;
class GFG
{
static void insert(List<int> heap, int value)
{
// Add the new element to the end of the heap
heap.Add(value);
// Get the index of the last element
int index = heap.Count - 1;
// Compare the new element with
// its parent and swap if necessary
while (index > 0 && heap[(index - 1) / 2] > heap[index])
{
int temp = heap[index];
heap[index] = heap[(index - 1) / 2];
heap[(index - 1) / 2] = temp;
// Move up the tree to the
// parent of the current element
index = (index - 1) / 2;
}
}
static void Main()
{
List<int> arr = new List<int>();
int[] values = {10, 3, 2, 4, 5, 1};
int n = values.Length;
for (int i = 0; i < n; i++)
{
insert(arr, values[i]);
Console.Write("Inserted " + values[i] + " into the min-heap: ");
for (int j = 0; j < arr.Count; j++)
{
Console.Write(arr[j] + " ");
}
Console.WriteLine();
}
}
}
JavaScript
function insert(heap, value) {
// Add the new element to the end of the heap
heap.push(value);
// Get the index of the last element
let index = heap.length - 1;
// Compare the new element with
// its parent and swap if necessary
while (index > 0 && heap[Math.floor((index - 1) / 2)] > heap[index]) {
let temp = heap[index];
heap[index] = heap[Math.floor((index - 1) / 2)];
heap[Math.floor((index - 1) / 2)] = temp;
// Move up the tree to the
// parent of the current element
index = Math.floor((index - 1) / 2);
}
}
//Driver Code
let arr = [];
let values = [10, 3, 2, 4, 5, 1];
let n = values.length;
for (let i = 0; i < n; i++) {
insert(arr, values[i]);
process.stdout.write(`Inserted ${values[i]} into the min-heap: `);
for (let j = 0; j < arr.length; j++) {
process.stdout.write(arr[j] + " ");
}
console.log();
}
OutputInserted 10 into the min-heap: 10
Inserted 3 into the min-heap: 3 10
Inserted 2 into the min-heap: 2 10 3
Inserted 4 into the min-heap: 2 4 3 10
Inserted 5 into the min-heap: 2 4 3 10 5
Inserted ...
Deletion -O(long n) Time and O(n) Space
Removing the smallest element (the root) from a Min-Heap involves the following steps:
- Replace the root (or the element to be deleted) with the last element in the heap.
- Remove the last element from the heap, since it has been moved to the root.
- Heapify-down: The element now at the root may violate the Min-Heap property, so perform heapify starting from the root to restore the heap property.
Illustration:
C++
#include <iostream>
#include <vector>
using namespace std;
void insert(vector<int>& heap, int value)
{
// Add the new element to the end of the heap
heap.push_back(value);
// Get the index of the last element
int index = heap.size() - 1;
// Compare the new element with its parent and swap if
// necessary
while (index > 0
&& heap[(index - 1) / 2] > heap[index]) {
swap(heap[index], heap[(index - 1) / 2]);
// Move up the tree to the parent of the current
// element
index = (index - 1) / 2;
}
}
// Function to delete a node from the min-heap
void deleteMin(vector<int>& heap, int value)
{
// Find the index of the element to be deleted
int index = -1;
for (int i = 0; i < heap.size(); i++) {
if (heap[i] == value) {
index = i;
break;
}
}
// If the element is not found, return
if (index == -1) {
return;
}
// Replace the element to be deleted with the last
// element
heap[index] = heap[heap.size() - 1];
// Remove the last element
heap.pop_back();
// Heapify the tree starting from the element at the
// deleted index
while (true) {
int left_child = 2 * index + 1;
int right_child = 2 * index + 2;
int smallest = index;
if (left_child < heap.size()
&& heap[left_child] < heap[smallest]) {
smallest = left_child;
}
if (right_child < heap.size()
&& heap[right_child] < heap[smallest]) {
smallest = right_child;
}
if (smallest != index) {
swap(heap[index], heap[smallest]);
index = smallest;
}
else {
break;
}
}
}
int main()
{
vector<int>arr;
vector<int>values = { 13, 16, 31, 41, 51, 100 };
int n = values.size();
for (int i = 0; i < n; i++) {
insert(arr, values[i]);
}
cout << "Initial heap: ";
for (int j = 0; j < arr.size(); j++) {
cout << arr[j] << " ";
}
cout << endl;
deleteMin(arr, 13);
cout << "Heap after deleting 13: ";
for (int j = 0; j < arr.size(); j++) {
cout << arr[j] << " ";
}
cout << endl;
return 0;
}
Java
import java.util.ArrayList;
public class GFG {
public static void insert(ArrayList<Integer> heap, int value) {
// Add the new element to the end of the heap
heap.add(value);
// Get the index of the last element
int index = heap.size() - 1;
// Compare the new element with its parent and swap if
// necessary
while (index > 0 && heap.get((index - 1) / 2) > heap.get(index)) {
int temp = heap.get(index);
heap.set(index, heap.get((index - 1) / 2));
heap.set((index - 1) / 2, temp);
// Move up the tree to the parent of the current
// element
index = (index - 1) / 2;
}
}
// Function to delete a node from the min-heap
public static void deleteMin(ArrayList<Integer> heap, int value) {
// Find the index of the element to be deleted
int index = -1;
for (int i = 0; i < heap.size(); i++) {
if (heap.get(i) == value) {
index = i;
break;
}
}
// If the element is not found, return
if (index == -1) {
return;
}
// Replace the element to be deleted with the last
// element
heap.set(index, heap.get(heap.size() - 1));
// Remove the last element
heap.remove(heap.size() - 1);
// Heapify the tree starting from the element at the
// deleted index
while (true) {
int left_child = 2 * index + 1;
int right_child = 2 * index + 2;
int smallest = index;
if (left_child < heap.size() && heap.get(left_child) < heap.get(smallest)) {
smallest = left_child;
}
if (right_child < heap.size() && heap.get(right_child) < heap.get(smallest)) {
smallest = right_child;
}
if (smallest != index) {
int temp = heap.get(index);
heap.set(index, heap.get(smallest));
heap.set(smallest, temp);
index = smallest;
} else {
break;
}
}
}
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
int[] values = {13, 16, 31, 41, 51, 100};
int n = values.length;
for (int i = 0; i < n; i++) {
insert(arr, values[i]);
}
System.out.print("Initial heap: ");
for (int j = 0; j < arr.size(); j++) {
System.out.print(arr.get(j) + " ");
}
System.out.println();
deleteMin(arr, 13);
System.out.print("Heap after deleting 13: ");
for (int j = 0; j < arr.size(); j++) {
System.out.print(arr.get(j) + " ");
}
System.out.println();
}
}
Python
def insert(heap, value):
# Add the new element to the end of the heap
heap.append(value)
# Get the index of the last element
index = len(heap) - 1
# Compare the new element with its parent and swap if
# necessary
while index > 0 and heap[(index - 1) // 2] > heap[index]:
heap[index], heap[(index - 1) // 2] = heap[(index - 1) // 2], heap[index]
# Move up the tree to the parent of the current
# element
index = (index - 1) // 2
# Function to delete a node from the min-heap
def deleteMin(heap, value):
# Find the index of the element to be deleted
index = -1
for i in range(len(heap)):
if heap[i] == value:
index = i
break
# If the element is not found, return
if index == -1:
return
# Replace the element to be deleted with the last
# element
heap[index] = heap[-1]
# Remove the last element
heap.pop()
# Heapify the tree starting from the element at the
# deleted index
while True:
left_child = 2 * index + 1
right_child = 2 * index + 2
smallest = index
if left_child < len(heap) and heap[left_child] < heap[smallest]:
smallest = left_child
if right_child < len(heap) and heap[right_child] < heap[smallest]:
smallest = right_child
if smallest != index:
heap[index], heap[smallest] = heap[smallest], heap[index]
index = smallest
else:
break
if __name__ == "__main__":
arr = []
values = [13, 16, 31, 41, 51, 100]
n = len(values)
for i in range(n):
insert(arr, values[i])
print("Initial heap: ", end="")
for val in arr:
print(val, end=" ")
print()
deleteMin(arr, 13)
print("Heap after deleting 13: ", end="")
for val in arr:
print(val, end=" ")
print()
C#
using System;
using System.Collections.Generic;
class GFG
{
static void insert(List<int> heap, int value)
{
// Add the new element to the end of the heap
heap.Add(value);
// Get the index of the last element
int index = heap.Count - 1;
// Compare the new element with its parent and swap if
// necessary
while (index > 0 && heap[(index - 1) / 2] > heap[index])
{
int temp = heap[index];
heap[index] = heap[(index - 1) / 2];
heap[(index - 1) / 2] = temp;
// Move up the tree to the parent of the current
// element
index = (index - 1) / 2;
}
}
// Function to delete a node from the min-heap
static void deleteMin(List<int> heap, int value)
{
// Find the index of the element to be deleted
int index = -1;
for (int i = 0; i < heap.Count; i++)
{
if (heap[i] == value)
{
index = i;
break;
}
}
// If the element is not found, return
if (index == -1)
{
return;
}
// Replace the element to be deleted with the last
// element
heap[index] = heap[heap.Count - 1];
// Remove the last element
heap.RemoveAt(heap.Count - 1);
// Heapify the tree starting from the element at the
// deleted index
while (true)
{
int left_child = 2 * index + 1;
int right_child = 2 * index + 2;
int smallest = index;
if (left_child < heap.Count && heap[left_child] < heap[smallest])
{
smallest = left_child;
}
if (right_child < heap.Count && heap[right_child] < heap[smallest])
{
smallest = right_child;
}
if (smallest != index)
{
int temp = heap[index];
heap[index] = heap[smallest];
heap[smallest] = temp;
index = smallest;
}
else
{
break;
}
}
}
static void Main()
{
List<int> arr = new List<int>();
int[] values = { 13, 16, 31, 41, 51, 100 };
int n = values.Length;
for (int i = 0; i < n; i++)
{
insert(arr, values[i]);
}
Console.Write("Initial heap: ");
for (int j = 0; j < arr.Count; j++)
{
Console.Write(arr[j] + " ");
}
Console.WriteLine();
deleteMin(arr, 13);
Console.Write("Heap after deleting 13: ");
for (int j = 0; j < arr.Count; j++)
{
Console.Write(arr[j] + " ");
}
Console.WriteLine();
}
}
JavaScript
function insert(heap, value) {
// Add the new element to the end of the heap
heap.push(value);
// Get the index of the last element
let index = heap.length - 1;
// Compare the new element with its parent and swap if
// necessary
while (index > 0 && heap[Math.floor((index - 1) / 2)] > heap[index]) {
let temp = heap[index];
heap[index] = heap[Math.floor((index - 1) / 2)];
heap[Math.floor((index - 1) / 2)] = temp;
// Move up the tree to the parent of the current
// element
index = Math.floor((index - 1) / 2);
}
}
// Function to delete a node from the min-heap
function deleteMin(heap, value) {
// Find the index of the element to be deleted
let index = -1;
for (let i = 0; i < heap.length; i++) {
if (heap[i] === value) {
index = i;
break;
}
}
// If the element is not found, return
if (index === -1) return;
// Replace the element to be deleted with the last
// element
heap[index] = heap[heap.length - 1];
// Remove the last element
heap.pop();
// Heapify the tree starting from the element at the
// deleted index
while (true) {
let left_child = 2 * index + 1;
let right_child = 2 * index + 2;
let smallest = index;
if (left_child < heap.length && heap[left_child] < heap[smallest]) {
smallest = left_child;
}
if (right_child < heap.length && heap[right_child] < heap[smallest]) {
smallest = right_child;
}
if (smallest !== index) {
let temp = heap[index];
heap[index] = heap[smallest];
heap[smallest] = temp;
index = smallest;
} else {
break;
}
}
}
// Driver code
let arr = [];
const values = [13, 16, 31, 41, 51, 100];
const n = values.length;
for (let i = 0; i < n; i++) {
insert(arr, values[i]);
}
process.stdout.write("Initial heap: ");
for (let j = 0; j < arr.length; j++) {
process.stdout.write(arr[j] + " ");
}
console.log();
deleteMin(arr, 13);
process.stdout.write("Heap after deleting 13: ");
for (let j = 0; j < arr.length; j++) {
process.stdout.write(arr[j] + " ");
}
console.log();
OutputInitial heap: 13 16 31 41 51 100
Heap after deleting 13: 16 41 31 100 51
Peek operation - O(1) Time and O(n) Space
To access the minimum element (i.e., the root of the heap), the value of the root node is returned.
C++
#include <iostream>
#include <vector>
using namespace std;
// Function to insert an element into min-heap
void insert(vector<int>& heap, int value) {
// Add the new element at the end
heap.push_back(value);
// Heapify-up to maintain min-heap property
int index = heap.size() - 1;
while (index > 0 && heap[(index - 1) / 2] > heap[index]) {
swap(heap[index], heap[(index - 1) / 2]);
index = (index - 1) / 2;
}
}
// Function to get the peak element of min-heap
int top(const vector<int>& heap) {
if (!heap.empty())
// Root element
return heap[0];
return -1;
}
int main() {
vector<int> minHeap;
// Insert elements into the min-heap
insert(minHeap, 51);
insert(minHeap, 41);
insert(minHeap, 31);
insert(minHeap, 16);
insert(minHeap, 13);
// Get the peak element (smallest in min-heap)
int peakElement = top(minHeap);
cout << "Peak element: " << peakElement << endl;
return 0;
}
Java
import java.util.ArrayList;
public class GFG {
// Function to insert an element into min-heap
public static void insert(ArrayList<Integer> heap, int value) {
// Add the new element at the end
heap.add(value);
// Heapify-up to maintain min-heap property
int index = heap.size() - 1;
while (index > 0 && heap.get((index - 1) / 2) > heap.get(index)) {
int temp = heap.get(index);
heap.set(index, heap.get((index - 1) / 2));
heap.set((index - 1) / 2, temp);
index = (index - 1) / 2;
}
}
// Function to get the peak element of min-heap
public static int top(ArrayList<Integer> heap) {
if (!heap.isEmpty())
// Root element
return heap.get(0);
return -1;
}
public static void main(String[] args) {
ArrayList<Integer> minHeap = new ArrayList<>();
// Insert elements into the min-heap
insert(minHeap, 51);
insert(minHeap, 41);
insert(minHeap, 31);
insert(minHeap, 16);
insert(minHeap, 13);
// Get the peak element (smallest in min-heap)
int peakElement = top(minHeap);
System.out.println("Peak element: " + peakElement);
}
}
Python
# Function to insert an element into min-heap
def insert(heap, value):
# Add the new element at the end
heap.append(value)
# Heapify-up to maintain min-heap property
index = len(heap) - 1
while index > 0 and heap[(index - 1) // 2] > heap[index]:
heap[index], heap[(index - 1) //
2] = heap[(index - 1) // 2], heap[index]
index = (index - 1) // 2
# Function to get the peak element of min-heap
def top(heap):
if heap:
# Root element
return heap[0]
return -1
if __name__ == "__main__":
minHeap = []
# Insert elements into the min-heap
insert(minHeap, 51);
insert(minHeap, 41);
insert(minHeap, 31);
insert(minHeap, 16);
insert(minHeap, 13);
# Get the peak element (smallest in min-heap)
peakElement = top(minHeap)
print("Peak element:", peakElement)
C#
using System;
using System.Collections.Generic;
class GFG
{
// Function to insert an element into min-heap
static void insert(List<int> heap, int value)
{
// Add the new element at the end
heap.Add(value);
// Heapify-up to maintain min-heap property
int index = heap.Count - 1;
while (index > 0 && heap[(index - 1) / 2] > heap[index])
{
int temp = heap[index];
heap[index] = heap[(index - 1) / 2];
heap[(index - 1) / 2] = temp;
index = (index - 1) / 2;
}
}
// Function to get the peak element of min-heap
static int top(List<int> heap)
{
if (heap.Count > 0)
// Root element
return heap[0];
return -1;
}
static void Main()
{
List<int> minHeap = new List<int>();
// Insert elements into the min-heap
insert(minHeap, 51);
insert(minHeap, 51);
insert(minHeap, 41);
insert(minHeap, 31);
insert(minHeap, 16);
insert(minHeap, 13);
// Get the peak element (smallest in min-heap)
int peakElement = top(minHeap);
Console.WriteLine("Peak element: " + peakElement);
}
}
JavaScript
// Function to insert an element into min-heap
function insert(heap, value) {
// Add the new element at the end
heap.push(value);
// Heapify-up to maintain min-heap property
let index = heap.length - 1;
while (index > 0 && heap[Math.floor((index - 1) / 2)] > heap[index]) {
let temp = heap[index];
heap[index] = heap[Math.floor((index - 1) / 2)];
heap[Math.floor((index - 1) / 2)] = temp;
index = Math.floor((index - 1) / 2);
}
}
// Function to get the peak element of min-heap
function top(heap) {
if (heap.length > 0) {
// Root element
return heap[0];
}
return -1;
}
// driver code
let minHeap = [];
// Insert elements into the min-heap
insert(minHeap, 51);
insert(minHeap, 41);
insert(minHeap, 31);
insert(minHeap, 16);
insert(minHeap, 13);
// Get the peak element (smallest in min-heap)
let peakElement = top(minHeap);
console.log("Peak element:", peakElement);
Heapify -O(n) Time and O(n) Space
The heapify operation is used to place an element in its correct position within the heap so that the heap property is maintained.
A heapify operation can also be used to create a min heap from an unsorted array. This is done by starting at the last non-leaf node and repeatedly performing the "heapify down" operation until all nodes satisfy the heap property.
C++
#include <iostream>
#include <vector>
using namespace std;
void heapify(vector<int> &arr, int i, int n) {
int smallest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
// If left child exists and is smaller than root
if (l < n && arr[l] < arr[smallest])
smallest = l;
// If right child exists and is smaller than smallest so far
if (r < n && arr[r] < arr[smallest])
smallest = r;
// If smallest is not root,
//swap and continue heapifying
if (smallest != i) {
swap(arr[i], arr[smallest]);
// Recursively heapify
heapify(arr, smallest, n);
}
}
int main() {
vector<int> arr = {2, 3, 10, 4, 5, 1};
cout << "Original array: ";
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
// Build min-heap: perform heapify from last
//non-leaf node up to root
for (int i = arr.size()/2 - 1; i >= 0; i--)
heapify(arr, i, arr.size());
// Print array after min-heapify
cout << "\nMin-Heap after heapify operation: ";
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
public class GFG {
public static void heapify(int[] arr, int i, int n) {
int smallest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
// If left child exists and is smaller than root
if (l < n && arr[l] < arr[smallest])
smallest = l;
// If right child exists and is smaller than smallest so far
if (r < n && arr[r] < arr[smallest])
smallest = r;
// If smallest is not root, swap and continue heapifying
if (smallest != i) {
int temp = arr[i];
arr[i] = arr[smallest];
arr[smallest] = temp;
// Recursively heapify
heapify(arr, smallest, n);
}
}
public static ArrayList<Integer> buildMinHeap(int[] arr) {
int n = arr.length;
// Build min-heap
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, i, n);
// Convert array to ArrayList before returning
ArrayList<Integer> result = new ArrayList<>();
for (int x : arr)
result.add(x);
return result;
}
public static void main(String[] args) {
int[] arr = {2, 3, 10, 4, 5, 1};
System.out.print("Original array: ");
for (int x : arr)
System.out.print(x + " ");
// Build min-heap: perform heapify from last
//non-leaf node up to root
ArrayList<Integer> minHeap = buildMinHeap(arr);
// Print array after min-heapify
System.out.print("\nMin-Heap after heapify operation: ");
for (int x : minHeap)
System.out.print(x + " ");
}
}
Python
def heapify(arr, i, n):
smallest = i
l = 2 * i + 1
r = 2 * i + 2
# If left child exists and is smaller than root
if l < n and arr[l] < arr[smallest]:
smallest = l
# If right child exists and is smaller than smallest so far
if r < n and arr[r] < arr[smallest]:
smallest = r
# If smallest is not root,
# swap and continue heapifying
if smallest != i:
arr[i], arr[smallest] = arr[smallest], arr[i]
# Recursively heapify
heapify(arr, smallest, n)
if __name__ == "__main__":
arr = [2, 3, 10, 4, 5, 1]
# Print original array
print("Original array: ", " ".join(str(x) for x in arr))
# Build min-heap: perform heapify from last non-leaf node up to root
for i in range(len(arr) // 2 - 1, -1, -1):
heapify(arr, i, len(arr))
print("Min-Heap after heapify operation: ", " ".join(str(x) for x in arr))
C#
using System;
using System.Collections.Generic;
class GFG
{
static void heapify(int[] arr, int i, int n)
{
int smallest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
// If left child exists and is smaller than root
if (l < n && arr[l] < arr[smallest])
smallest = l;
// If right child exists and is smaller than smallest so far
if (r < n && arr[r] < arr[smallest])
smallest = r;
// If smallest is not root,
// swap and continue heapifying
if (smallest != i)
{
int temp = arr[i];
arr[i] = arr[smallest];
arr[smallest] = temp;
// Recursively heapify
heapify(arr, smallest, n);
}
}
static List<int> buildMinHeap(int[] arr)
{
int n = arr.Length;
// Build min-heap: perform heapify from last
// non-leaf node up to root
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, i, n);
// Convert array to List<int>
List<int> result = new List<int>(arr);
return result;
}
static void Main()
{
int[] arr = { 2, 3, 10, 4, 5, 1 };
Console.Write("Original array: ");
for (int i = 0; i < arr.Length; i++)
Console.Write(arr[i] + " ");
List<int> minHeap = buildMinHeap(arr);
Console.Write("\nMin-Heap after heapify operation: ");
for (int i = 0; i < minHeap.Count; i++)
Console.Write(minHeap[i] + " ");
}
}
JavaScript
function heapify(arr, i, n) {
let smallest = i;
let l = 2 * i + 1;
let r = 2 * i + 2;
// If left child exists and is smaller than root
if (l < n && arr[l] < arr[smallest])
smallest = l;
// If right child exists and is smaller than smallest so far
if (r < n && arr[r] < arr[smallest])
smallest = r;
// If smallest is not root,
// swap and continue heapifying
if (smallest !== i) {
let temp = arr[i];
arr[i] = arr[smallest];
arr[smallest] = temp;
// Recursively heapify
heapify(arr, smallest, n);
}
}
// Main driver code
let arr = [ 2, 3, 10, 4, 5, 1];
console.log("Original array: " + arr.join(" "));
// Build min-heap: perform heapify from last
// non-leaf node up to root
for (let i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
heapify(arr, i, arr.length);
}
console.log("Min-Heap after heapify operation: " + arr.join(" "));
OutputOriginal array: 2 3 10 4 5 1
Min-Heap after heapify operation: 1 3 2 4 5 10
Min-Heap Vs Max-Heap
Applications of Min-Heap Data Structure
- Heap Sort: Min-heap is used to implement heap sort, an efficient O(nlogn) sorting algorithm.
- Priority Queue: Min-heap ensures the smallest element is always at the root, enabling efficient priority queue operations.
- Dijkstra’s Algorithm: Min-heap stores vertices by minimum distance for efficient shortest-path computation.
- Huffman Coding: Min-heap implements a priority queue to build optimal prefix codes.
- Merge K Sorted Arrays: Min-heap efficiently merges K sorted arrays into one sorted array.
Advantages of Min-heap Data Structure
- Fast Insertion and Deletion: Supports insertion and removal in O(logn) time, maintaining heap property efficiently.
- Quick Access to Minimum: The smallest element is always at the root, retrievable in O(1) time.
- Compact Storage: Can be implemented using arrays, saving memory compared to pointer-based structures.
- Heap-based Sorting: Enables efficient sorting algorithms like heap sort with O(nlogn) complexity.
- Wide Applicability: Useful in scheduling, graph traversal, data compression, and other computational tasks.
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem