공부 기록/자료구조

Trees

와일 2026. 4. 1. 10:43
반응형

  배열, 링크드리스트 같은 linear 자료구조는 "앞-뒤" 관계만 표현할 수 있다. 트리는 계층적(hierarchical) 관계를 표현할 수 있는 첫 번째 nonlinear 자료구조다. 파일 시스템, 데이터베이스, GUI 등 실제로 굉장히 많은 곳에 쓰인다.


1. 용어 정리

        A          ← level 0
       / \
      B   C        ← level 1
         / \
        D   E      ← level 2
           / \
          F   G    ← level 3
용어 설명 예시
Root 트리의 최상단 노드. 부모가 없다 A
Leaf / External node 자식이 없는 노드 B, D, F, G
Internal node 자식이 있는 노드 A, C, E
Sibling 같은 부모를 가진 노드 B와 C
Ancestor 위로 올라가는 모든 노드 G의 ancestor = E, C, A
Descendant 아래로 내려가는 모든 노드 C의 descendant = D, E, F, G
Level / Depth root에서 해당 노드까지의 거리. root = level 0 G의 level = 3
Height 트리 전체에서 가장 큰 level 위 트리의 height = 3
Degree 해당 노드의 자식 수 C의 degree = 2

2. Binary Tree

  모든 노드가 최대 2개의 자식을 가지는 트리. 자식은 왼쪽(left child)과 오른쪽(right child)으로 구분된다.

  • Proper binary tree: 모든 노드가 자식을 0개 또는 2개 가짐
  • Improper binary tree: 자식이 1개인 노드가 존재
      Proper          Improper
        A                A
       / \              / \
      B   C            B   C
     / \                \
    D   E                D

Properties

  n개의 노드, nE개의 외부 노드, nI개의 내부 노드, height h인 binary tree T에 대해:

항목 범위 최솟값 이유 최댓값 이유
n h+1 ≤ n ≤ 2^(h+1)-1 한쪽으로만 치우친 트리 모든 레벨이 꽉 찬 트리
nE 1 ≤ nE ≤ 2^h root만 있는 트리 level h의 노드가 전부 leaf
h log(n+1)-1 ≤ h ≤ n-1 균형잡힌 full binary tree 한쪽 자식만 있는 트리

3. 구현 방법

Linked Structure

  각 노드가 element, parent, left child, right child를 저장하는 포인터를 가진다.

[ parent | element | left | right ]

Array-Based (Level Numbering)

  노드의 위치를 index로 표현한다. root의 index = 0.

  • 왼쪽 자식: 2f(p) + 1
  • 오른쪽 자식: 2f(p) + 2
  • 부모: ⌊(f(p) - 1) / 2⌋
          A(0)
         /    \
       B(1)   C(2)
      /    \
    D(3)   E(4)
  Linked Array-Based
장점 메모리 효율적, 삽입/삭제 O(1) 부모/자식 접근이 산술 계산으로 O(1)
단점 포인터 overhead 치우친 트리일수록 메모리 낭비, 삽입/삭제 O(n)

 
트리의 operations는 크게 두 가지로 나뉜다.

Accessor Methods (트리를 변경하지 않음)

Method 설명
T.root() root 노드 반환
T.parent(p) p의 부모 반환
T.children(p) p의 자식들 반환
T.num_children(p) p의 자식 수 반환
T.is_root(p) p가 root인지 확인
T.is_leaf(p) p가 leaf인지 확인
len(T) 노드 수 반환
T.is_empty() 트리가 비어있는지 확인

Update Methods (트리를 변경함) — Binary Tree 전용

Method 설명
T.add_root(e) 빈 트리에 root 추가
T.add_left(p, e) p의 왼쪽 자식 추가
T.add_right(p, e) p의 오른쪽 자식 추가
T.replace(p, e) p의 element를 e로 교체
T.delete(p) p 삭제 (자식이 2개면 불가)
T.attach(p, T1, T2) leaf p에 T1, T2를 왼쪽/오른쪽 서브트리로 붙임

Time Complexity

Operation Running Time
len, is_empty O(1)
root, parent, left, right, children, num_children O(1)
is_root, is_leaf O(1)
depth(p) O(d+1)
height O(n)
add_root, add_left, add_right, replace, delete, attach O(1)

  대부분이 O(1)인 이유는 각 노드가 parent, left child, right child를 직접 포인터로 저장하고 있어서 바로 접근이 가능하기 때문이다. depth는 root까지 올라가야 하고, height는 모든 노드를 확인해야 해서 예외적으로 더 걸린다.


4. Traversal

  트리의 모든 노드를 방문하는 방법. 목적에 따라 순서가 달라진다.

Preorder — 부모 → 왼쪽 → 오른쪽

부모를 먼저 방문한다. 목차처럼 구조를 순서대로 출력할 때 적합하다.

Postorder — 왼쪽 → 오른쪽 → 부모

자식을 먼저 방문한다. 사칙연산 트리에서 값을 계산할 때처럼, 자식의 결과가 있어야 부모를 처리할 수 있을 때 적합하다.

Inorder — 왼쪽 → 부모 → 오른쪽 (binary tree 전용)

왼쪽 서브트리 → 루트 → 오른쪽 서브트리 순으로 방문한다. BST(binary search tree)에서 inorder traversal을 하면 오름차순 정렬된 결과가 나온다.

Breadth-First (BFS) — 레벨 순서대로

같은 레벨을 전부 방문한 뒤 다음 레벨로 내려간다. 재귀가 아닌 Queue로 구현한다.

각 노드를 방문할 때 그 자식들을 Queue에 넣어두면, 현재 레벨을 다 처리한 뒤 자연스럽게 다음 레벨로 넘어간다.

Algorithm breadthfirst(T):
    Q.enqueue(T.root())
    while Q not empty:
        p = Q.dequeue()
        visit p
        for each child c of p:
            Q.enqueue(c)

게임 트리처럼 "앞으로 h수 안에 가능한 모든 경우의 수"를 탐색할 때 유용하다.


5. Binary Search Tree (BST)

BST는 binary tree에 다음 조건을 추가한 것이다:

  • 왼쪽 서브트리의 모든 값 < root
  • 오른쪽 서브트리의 모든 값 > root
          13
         /  \
        9   20
       / \  / \
      3  10 19 23

이 조건 덕분에 inorder traversal을 하면 항상 정렬된 순서로 출력된다.

삭제

  • Leaf 삭제: 그냥 제거
  • 자식이 1개: 해당 노드를 자식으로 대체
  • 자식이 2개: 왼쪽 서브트리의 최댓값 또는 오른쪽 서브트리의 최솟값으로 대체
    • 최솟값 찾기: 오른쪽 서브트리에서 왼쪽으로 계속 내려가면 된다

Time Complexity

Operation Sorted Array BST
Search O(log n) O(h)
Insert O(n) O(h)
Delete O(n) O(h)

  BST의 h는 log(n+1)-1 ≤ h ≤ n-1이다. 트리가 균형잡혀 있으면 h ≈ log n이라 sorted array보다 삽입/삭제가 훨씬 빠르지만, 한쪽으로 치우치면 h = n-1이 되어 O(n)으로 나빠진다. 이를 해결하려면 트리의 균형을 유지해야 한다 → Chapter 11에서 다룸.


6. 정리

  트리는 단순히 빠른 자료구조가 아니다. 데이터가 가진 계층적 관계 자체를 표현하기 위한 구조다. BST처럼 순서 관계를 트리 구조에 얹으면, 삽입/삭제가 O(n)인 sorted array의 한계를 넘을 수 있다.

반응형

'공부 기록 > 자료구조' 카테고리의 다른 글

Map and Hash  (0) 2026.06.16
Priority Queues and Heaps  (5) 2026.04.17
Queues and Stacks  (0) 2026.03.23
Recursion  (0) 2026.03.23
Arrays & Linked Lists  (0) 2026.03.14