본문으로 건너뛰기
자료구조 · 알고리즘 기초집LESSON 17

이진 탐색 트리: 삽입·검색·삭제의 원리

난이도초급 → 중급 입문
예상 시간40분
선수지식이전 강의

17강. 이진 탐색 트리: 삽입·검색·삭제의 원리

1. 이번 강의에서 해결할 문제​

정렬된 순서를 유지하면서 점수를 계속 추가하고 찾고 싶지만 배열 중간 삽입은 원소 이동이 필요합니다.

2. 학습 목표​

3. 핵심 개념​

이진 탐색 트리(BST)는 각 노드보다 작은 키를 왼쪽, 큰 키를 오른쪽에 둡니다. 중복 정책은 개수 저장, 한쪽 배치, 거부 중 하나를 명시해야 합니다. 삭제는 리프, 자식 하나, 자식 둘의 경우로 나뉘며 자식 둘이면 오른쪽 하위 트리의 최솟값 같은 후계자로 대체합니다. 이 구조 자체는 균형을 보장하지 않습니다.

4. 단계별 실습​

1. 예제 파일 작성​

실행 환경: 코드 편집기

실행 위치: C:\dev\game-ranking-algorithms

실행 전 확인: 같은 이름의 파일이 있다면 덮어쓰기 전에 Git diff로 변경 범위를 확인합니다. 선택한 LTS JDK의 java -version과 javac -version이 모두 실행되어야 합니다.

대상 파일: src/ScoreSearchTree.java

src/ScoreSearchTree.java
public class ScoreSearchTree {
static final class Node {
int score, count = 1;
Node left, right;
Node(int score) { this.score = score; }
}
private Node root;

void add(int score) { root = add(root, score); }
Node add(Node node, int score) {
if (node == null) return new Node(score);
if (score < node.score) node.left = add(node.left, score);
else if (score > node.score) node.right = add(node.right, score);
else node.count++;
return node;
}
int count(int score) {
Node node = root;
while (node != null) {
if (score == node.score) return node.count;
node = score < node.score ? node.left : node.right;
}
return 0;
}

void remove(int score) { root = remove(root, score); }
Node remove(Node node, int score) {
if (node == null) return null;
if (score < node.score) node.left = remove(node.left, score);
else if (score > node.score) node.right = remove(node.right, score);
else if (node.count > 1) node.count--;
else if (node.left == null) return node.right;
else if (node.right == null) return node.left;
else {
Node successor = min(node.right);
node.score = successor.score;
node.count = successor.count;
node.right = removeAll(node.right, successor.score);
}
return node;
}
Node removeAll(Node node, int score) {
if (score < node.score) node.left = removeAll(node.left, score);
else if (score > node.score) node.right = removeAll(node.right, score);
else return node.right;
return node;
}
Node min(Node node) {
while (node.left != null) node = node.left;
return node;
}

public static void main(String[] args) {
ScoreSearchTree tree = new ScoreSearchTree();
for (int score : new int[]{1000, 700, 1300, 1000}) tree.add(score);
System.out.println("1000점 개수: " + tree.count(1000));
tree.remove(1000);
tree.remove(700);
System.out.println("삭제 후 1000점 개수: " + tree.count(1000));
System.out.println("삭제 후 700점 개수: " + tree.count(700));
System.out.println("900점 개수: " + tree.count(900));
}
}

2. PowerShell에서 컴파일·실행​

실행 환경: Windows PowerShell

실행 위치: C:\dev\game-ranking-algorithms

실행 전 확인: src/ScoreSearchTree.java가 저장되었고 out 폴더에는 삭제해도 되는 컴파일 결과만 있는지 확인합니다.

대상: src/ScoreSearchTree.java와 out 아래 생성되는 class 파일

Windows PowerShell
Set-Location C:\dev\game-ranking-algorithms
New-Item -ItemType Directory -Force .\out | Out-Null
javac -Xlint:all -d .\out .\src\ScoreSearchTree.java
java -cp .\out ScoreSearchTree

예상 결과: 1000점 개수는 2에서 한 번 삭제 후 1이 되고, 삭제한 700점과 존재하지 않는 900점 개수는 0이 출력됩니다.

실행 시간은 PC의 CPU·메모리, JDK 버전, JVM 워밍업, 백그라운드 작업과 입력 분포에 따라 달라질 수 있습니다. 측정값은 같은 조건에서 여러 번 비교하고 Big-O 분석과 함께 해석합니다.

5. 코드와 알고리즘이 동작하는 이유​

비교할 때마다 왼쪽 또는 오른쪽 하위 트리 하나만 선택합니다. 삭제는 중복 개수를 줄이거나 자식 0·1개를 바로 연결하고, 자식 둘이면 오른쪽의 최소 후계자와 그 중복 개수를 옮겨 순서 불변식을 지킵니다. 높이 h에 대해 삽입·검색·삭제는 O(h)입니다. 균형에 가까우면 평균 O(log n)이지만 정렬 순서로 삽입해 편향되면 최악 O(n)입니다. 노드는 O(n) 공간을 사용합니다.

6. 자주 하는 실수와 해결법​

7. 직접 실습​

8. 이해 점검 질문 3개​

9. 핵심 요약​

MINI QUIZ

이진 탐색 트리: 삽입·검색·삭제의 원리 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“이진 탐색 트리: 삽입·검색·삭제의 원리”의 위험한 선택을 피하려면 어떤 원칙을 적용해야 하나요?
  2. 문제 2‘중복 키 정책 없이 한쪽에 계속 넣기’ 상태에 관한 “이진 탐색 트리: 삽입·검색·삭제의 원리” 본문의 설명으로 가장 알맞은 것은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

17강. 이진 탐색 트리: 삽입·검색·삭제의 원리 미완료 상태