Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 두 개의 최대 힙(Max Heap) 병합하기


문제 개요

배열 형태로 주어진 두 개의 이진 최대 힙(binary max heap)을 하나의 최대 힙으로 병합하는 것이 목표입니다. 병합된 결과 역시 최대 힙의 성질, 즉 부모 노드가 항상 자식 노드보다 크거나 같은 구조를 유지해야 합니다.

Heap1[] = {20, 17, 15, 10}
Heap2[] = {19, 13, 7}
Result[] = {20, 19, 15, 13, 17, 7, 10}

알고리즘

두 힙을 병합하는 절차는 다음과 같이 단순합니다.

1. 병합 결과를 저장할 새로운 배열을 생성합니다.
2. 주어진 두 배열의 요소를 순서대로 결과 배열에 모두 복사합니다.
3. 병합된 전체 배열에 대해 힙 생성(heapify) 과정을 수행하여 하나의 완전한 최대 힙을 구성합니다.

C++ 구현 예제

아래 코드는 heapify 함수를 재귀적으로 호출해 힙 구조를 만들고, createMaxHeap 함수로 전체 배열을 최대 힙으로 변환한 뒤, mergeMaxHeaps 함수에서 두 힙을 하나로 합치는 과정을 보여줍니다.

#include <iostream>
#include <algorithm>
#define SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
using namespace std;

// 특정 인덱스를 기준으로 서브트리를 최대 힙 형태로 정렬
void heapify(int *arr, int n, int idx){
   if (idx >= n) {
      return;
   }
   int l = 2 * idx + 1;
   int r = 2 * idx + 2;
   int max;
   if (l < n && arr[l] > arr[idx]) {
      max = l;
   } else {
      max = idx;
   }
   if (r < n && arr[r] > arr[max]) {
      max = r;
   }
   if (max != idx) {
      swap(arr[max], arr[idx]);
      heapify(arr, n, max);
   }
}

// 마지막 부모 노드부터 루트까지 heapify를 호출해 최대 힙 생성
void createMaxHeap(int *arr, int n){
   for (int i = n / 2 - 1; i >= 0; --i) {
      heapify(arr, n, i);
   }
}

// 두 힙의 요소를 하나의 배열로 합친 뒤 전체를 다시 최대 힙으로 구성
void mergeMaxHeaps(int *arr1, int n1, int *arr2, int n2, int *result){
   merge(arr1, arr1 + n1, arr2, arr2 + n2, result);
   createMaxHeap(result, n1 + n2);
}

void displayHeap(int *arr, int n){
   for (int i = 0; i < n; ++i) {
     cout << arr[i] << " ";
   }
   cout << endl;
}

int main(){
   int heap1[] = {20, 17, 15, 10};
   int heap2[] = {19, 13, 7};
   int result[SIZE(heap1) + SIZE(heap2)];
   cout << "First max heap: " << endl;
   displayHeap(heap1, SIZE(heap1));
   cout << "Second max heap: " << endl;
   displayHeap(heap2, SIZE(heap2));
   mergeMaxHeaps(heap1, SIZE(heap1), heap2, SIZE(heap2), result);
   cout << "Merged max heap: " << endl;
   displayHeap(result, SIZE(result));
   return 0;
}

실행 결과

위 프로그램을 컴파일하고 실행하면 다음과 같은 출력이 생성됩니다.

First max heap:
20 17 15 10
Second max heap:
19 13 7
Merged max heap:
20 19 15 13 17 7 10

정리

이 방식은 두 힙의 요소를 단순히 합친 후 전체 배열에 대해 한 번의 힙 생성 과정을 수행하기 때문에, 시간 복잡도는 O(N + M)입니다(N, M은 각 힙의 크기). 요소 수가 많은 경우에도 효율적으로 동작하며, 병합된 결과는 항상 유효한 최대 힙 구조를 가지게 됩니다.