// education

이진 트리(Binary Tree) 순회와 이진 힙(Binary Heap) 메커니즘

**이진 트리(Binary Tree)**는 각 노드가 최대 2개의 자식 노드를 가지는 계층적 비선형 자료구조입니다. **이진 힙(Binary Heap)**은 완전 이진 트리 구조를 활용해 최댓값이나 최솟값을 $O(log N)$에 찾는 최적 자료구조입니다.


1. 이진 트리 노드 및 순회 (Preorder, Inorder, Postorder, Levelorder)

class Node:
    def __init__(self, item, left=None, right=None):
        self.item = item
        self.left = left
        self.right = right

# 전위 순회 (V -> L -> R)
def preorder(n):
    if n:
        print(n.item, end=' ')
        preorder(n.left)
        preorder(n.right)

# 레벨 순회 (Queue 활용)
from collections import deque
def levelorder(root):
    q = deque([root])
    while q:
        n = q.popleft()
        if n:
            print(n.item, end=' ')
            q.append(n.left)
            q.append(n.right)

2. 이진 힙 (Binary Heap) 메커니즘

이진 힙은 배열(List)로 효율적으로 표현됩니다.

class BHeap:
    def __init__(self, a):
        self.a = a  # [None] + 데이터
        self.N = len(a) - 1

    def create_heap(self):
        for i in range(self.N // 2, 0, -1):
            self.downheap(i)

    def insert(self, key):
        self.a.append(key)
        self.N += 1
        self.upheap(self.N)

    def upheap(self, j):
        while j > 1 and self.a[j // 2] > self.a[j]: # 최소 힙 조건
            self.a[j // 2], self.a[j] = self.a[j], self.a[j // 2]
            j = j // 2

    def delete_min(self):
        if self.N == 0:
            return None
        minimum = self.a[1]
        self.a[1] = self.a[self.N]
        self.a.pop()
        self.N -= 1
        self.downheap(1)
        return minimum

    def downheap(self, i):
        while 2 * i <= self.N:
            k = 2 * i
            if k < self.N and self.a[k] > self.a[k + 1]:
                k += 1
            if self.a[i] <= self.a[k]:
                break
            self.a[i], self.a[k] = self.a[k], self.a[i]
            i = k

3. 이진 힙 연산 복잡도 정리

연산 시간 복잡도 설명
최솟값/최댓값 조회 $O(1)$ 루트 노드(a[1]) 반환
새 요소 삽입 (Insert) $O(log N)$ 맨 뒤 삽입 후 upheap 실행
최댓값/최솟값 삭제 $O(log N)$ 루트 제거 후 맨 뒤 요소 이동 및 downheap
힙 생성 (Build Heap) $O(N)$ 배열 전체를 힙으로 만듦 (Linear Time)

4. 자주 묻는 질문 (Q&A)

Q. 힙 생성(Build Heap)이 $O(N log N)$이 아니라 $O(N)$인 이유는? A. 아래쪽 레벨의 노드 수(전체의 절반)는 높이가 0이어서 이동하지 않고, 위로 올라갈수록 노드 수($N/2^h$)는 절반으로 줄어듭니다. 이를 급수 계산하면 $sum (h / 2^h) = 2$가 되어 전체 연산량이 $O(N)$으로 수렴합니다.

← 이전스택(Stack), 큐(Queue), 덱(Deque)의 파이썬 구현 및 응용 다음 →탐색 트리 - 이진 탐색 트리(BST)와 자가 균형 AVL 트리 회전 연산