문제 4 · 실습 — 좌향 힙 병합
두 좌향 힙을 병합해 결과 트리와 각 노드의 널 경로 길이(npl)를 출력합니다. 트리는 오른쪽 자식을 위로, 왼쪽 자식을 아래로 눕혀 그립니다(들여쓰기가 깊을수록 아래 층).
cpp
#include <iostream>
#include <algorithm>
using namespace std;
struct Node {
int key, npl;
Node *left, *right;
Node(int k): key(k), npl(0), left(nullptr), right(nullptr) {}
};
int npl(Node* h){ return h ? h->npl : -1; }
int computeNpl(Node* h){
if(!h) return -1;
int l = computeNpl(h->left), r = computeNpl(h->right);
return h->npl = min(l, r) + 1;
}
Node* merge(Node* a, Node* b){
if(!a) return b;
if(!b) return a;
if(a->key > b->key) swap(a, b);
a->right = merge(a->right, b);
if(npl(a->left) < npl(a->right)) swap(a->left, a->right);
a->npl = npl(a->right) + 1;
return a;
}
void show(Node* h, int depth){
if(!h) return;
show(h->right, depth + 1);
for(int i = 0; i < depth; i++) cout << " ";
cout << h->key << " (npl=" << h->npl << ")\n";
show(h->left, depth + 1);
}
Node* N(int k){ return new Node(k); }
int main(){
// 힙 A: 루트 3
Node* a = N(3);
a->left = N(10); a->left->left = N(27); a->left->right = N(28);
a->right = N(16); a->right->left = N(33);
// 힙 B: 루트 4
Node* b = N(4);
b->left = N(11); b->left->left = N(32); b->left->left->left = N(50);
b->left->right = N(41);
b->right = N(12); b->right->left = N(22); b->right->left->left = N(33);
computeNpl(a);
computeNpl(b);
Node* m = merge(a, b);
cout << "병합 결과 (오른쪽=위, 왼쪽=아래):\n\n";
show(m, 0);
cout << "\n루트 = " << m->key
<< ", 루트 npl = " << m->npl
<< ", 좌·우 자식 = " << m->left->key << ", " << m->right->key << "\n";
return 0;
}