Efficient Sorting and Merging with Heap Data Structures

Heap Data Structure Implementation

Heaps are specialized tree-based data structures that satisfy the heap property. They are commonly used to implement priority queues and for efficient sorting algorithms. This article explores two practical applications of heaps: heap sort and sequence merging.

Heap Sort Implemantation

Heap sort is an efficient comparison-based sorting algorithm that leverages the heap data structure. The algorithm works by first building a max heap from the input data and then repeaetdly extracting the maximum element and placing it at the end of the array.

The key to implementing heap sort is the heapify function, which maintains the heap property. Here's an implementation in C++:

#include <iostream>
#include <algorithm>
#define MAX_SIZE 100005
using namespace std;

int dataCount;
int heapArray[MAX_SIZE];

// Function to maintain heap property
void heapify(int startIdx, int endIdx) {
    int parent = startIdx;
    int child = 2 * parent; // Left child
    
    while (child <= endIdx) {
        // Check if right child exists and is greater
        if (child + 1 <= endIdx && heapArray[child + 1] > heapArray[child]) {
            child++;
        }
        
        // If child is greater than parent, swap them
        if (heapArray[child] > heapArray[parent]) {
            swap(heapArray[parent], heapArray[child]);
            parent = child;
            child = 2 * parent;
        } else {
            break;
        }
    }
}

// Function to build a max heap
void buildMaxHeap() {
    for (int i = dataCount / 2; i >= 1; i--) {
        heapify(i, dataCount);
    }
}

// Main heap sort function
void performHeapSort() {
    buildMaxHeap();
    for (int i = dataCount; i > 1; i--) {
        swap(heapArray[1], heapArray[i]);
        heapify(1, i - 1);
    }
}

int main() {
    cin >> dataCount;
    for (int i = 1; i <= dataCount; i++) {
        cin >> heapArray[i];
    }

    performHeapSort();
    for (int i = 1; i <= dataCount; i++) {
        cout << heapArray[i] << " ";
    }
    cout << endl;
    return 0;
}

Sequence Merging Using Priority Queues

Another interesting application of heaps is in merging sequences efficiently. Given two arrays, we want to find the n smallest sums of elements from these arrays. A naive approach would generate all possible sums, but this leads to O(n²) time complexity, which is inefficient for large arrays.

A more efficient approach uses a priority queue (min-heap) to keep track of the smallest sums without generating all possibilities. Here's a time-efficient implementation:

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

const int MAX_VAL = 100002;

struct SumNode {
    int idx;      // Index in the first array
    int sumVal;   // Sum value
    
    // Overload the less than operator for priority queue
    bool operator<(const SumNode& other) const {
        return sumVal > other.sumVal; // For min-heap
    }
};

int main() {
    int n;
    int firstArr[MAX_VAL], secondArr[MAX_VAL];
    
    while (cin >> n) {
        // Read first array
        for (int i = 0; i < n; i++) {
            cin >> firstArr[i];
        }
        
        // Read second array
        for (int i = 0; i < n; i++) {
            cin >> secondArr[i];
        }
        
        // Priority queue to store sum nodes
        priority_queue<SumNode> minHeap;
        SumNode tempNode;
        
        // Initialize the heap with sums of each element in second array
        // with the first element of the first array
        for (int i = 0; i < n; i++) {
            tempNode.idx = 0;
            tempNode.sumVal = secondArr[i] + firstArr[0];
            minHeap.push(tempNode);
        }
        
        // Extract the n smallest sums
        for (int i = 0; i < n; i++) {
            SumNode current = minHeap.top();
            minHeap.pop();
            
            // If there are more elements in the first array,
            // add the next combination to the heap
            if (current.idx + 1 < n) {
                tempNode.idx = current.idx + 1;
                tempNode.sumVal = current.sumVal - firstArr[current.idx] + firstArr[tempNode.idx];
                minHeap.push(tempNode);
            }
            
            // Print the current smallest sum
            cout << current.sumVal << (i == n - 1 ? '\n' : ' ');
        }
    }
    
    return 0;
}

This implementation efficiently finds the n smallest sums by only considering necessary combinations, reducing the time complexity significantly compared to the brute-force approach.

Tags: heap heapsort priority-queue data-structures algorithms

Posted on Thu, 18 Jun 2026 16:37:37 +0000 by Eddie Fisher