Folders and files Name Name Last commit message
Last commit date
parent directory
View all files
Trie (트라이, 접두사 트리) (2026-07-28)
문자열의 집합을 표현하는 트리 자료구조 (Prefix Tree)
루트에서 노드로 내려가는 경로 가 곧 문자열의 접두사가 됨
접두사가 같은 문자열끼리 앞부분 노드를 공유 함
BST에서 문자열 검색은 O(M log N)이지만, 트라이는 문자열 개수 N과 무관하게 O(M)
(M = 문자열 길이, N = 집합에 든 문자열 개수)
배열(children[26]) 방식으로 구현 — 소문자 a~z만 대상
노드는 글자를 직접 저장하지 않음 → "부모의 몇 번째 칸에 매달렸는가"로 글자를 표현
idx = ch - 'a' (a=0, b=1, ... z=25) → 칸 번호가 곧 글자
isEnd(빨간 노드) = "이 노드에서 끝나는 문자열이 있다"는 표시 → 이게 사실상 삽입의 핵심
insert : 글자마다 자식 노드를 따라가거나 없으면 생성, 마지막에 isEnd = true
search : 경로 끝까지 도달 + isEnd == true 여야 true (단어 자체가 있는지)
startsWith : 경로만 존재하면 true (그 접두사로 시작하는 단어가 있는지)
search vs startsWith : "hi", "high"만 넣었을 때 search("h")는 false지만 startsWith("h")는 true
static 중첩 클래스 : Node를 static class로 선언 → 바깥 Trie 참조(숨은 필드)를 없애 메모리 절약
(노드가 수십만 개 생기므로 노드마다 붙는 숨은 참조가 그대로 낭비가 됨)
연산
시간 복잡도
삽입 (insert)
O(M)
검색 (search)
O(M)
접두사 검색 (startsWith)
O(M)
삭제 (delete)
O(M)
N(문자열 개수)과 무관하게 오직 문자열 길이 M에만 비례 (BST의 log N 항이 사라짐)
장점 : 문자열 삽입/검색이 O(M), 접두사 기반 연산(자동완성 등)에 강함
단점 : 메모리 낭비가 큼 — 배열 방식은 노드마다 안 쓰는 칸까지 26개를 확보
총 메모리 ≈ O(포인터 크기 × 26 × 총 노드 수)
완화: 배열 대신 HashMap<Character, Node>로 실제 등장한 문자만 저장
삭제 (delete) — 재귀로 내려갔다 올라오며 처리
삭제 방식은 2가지
isEnd만 끄기 : node.isEnd = false 한 줄. 노드는 남고 검색만 실패 (메모리 낭비)
노드까지 회수 : children[idx] = null(map은 remove)로 연결을 끊음 → GC가 수거 (우리 구현)
재귀 2단계
내려가는 길 : 글자를 따라 단어 끝까지 감 → 끝에서 isEnd = false (이게 삭제 본체)
올라오는 길 : 각 노드가 "나 지워도 되나?"를 아래에서부터 판단
노드를 실제로 지우는 조건 (둘 다 만족)
다른 단어의 끝이 아님 (isEnd == false)
자식이 하나도 없음 (아무도 그 경로를 안 씀)
반환값의 의미 : delete(...)의 return 값 = "부모야, 방금 다녀온 이 노드 끊어도 돼?"
true → 부모가 children[idx] = null로 실제로 끊음
false → 남겨야 함. 여기서 연쇄가 멈춤
트라이는 문자열을 통째로 저장하지 않음 → 글자는 칸 위치로, 단어 존재는 isEnd로 나눠 표현
문자열 특화 자료구조라 제네릭(Trie)보다 String 입력으로 고정하는 게 자연스러움
소문자 외 입력(대문자/공백/숫자)이 들어오면 idx가 0~25 범위를 벗어나 예외 발생 주의
자바 GC: children[idx] = null로 참조를 끊으면 아무도 안 가리키는 노드는 자동 회수됨
Trie - HashMap 방식 구현 (2026-08-03)
배열 방식은 노드마다 안 쓰는 칸까지 26개를 확보 → 메모리 낭비
HashMap 방식은 실제 등장한 문자만 저장 → 메모리 절약 + 소문자 외 문자도 자연스럽게 처리
Node[] children (배열 26칸) → Map<Character, Node> children (HashMap) 으로 교체
로직(insert/search/startsWith/delete)은 배열 버전과 100% 동일 — 자식 저장/접근 방식만 바뀜
idx = ch - 'a' 변환이 사라짐 : 배열은 "몇 번째 칸"이 글자였지만, map은 문자 ch를 그대로 key로 씀
isEmpty() 헬퍼 삭제 : 배열은 26칸을 직접 순회했지만, map은 children.isEmpty() 한 줄로 대체
범위 예외 걱정 없음: 대문자·숫자·한글도 key로 그대로 사용 가능
항목
배열 children[26]
HashMap
자식 저장
항상 26칸 확보
등장한 문자만 저장
접근 속도
O(1) (가장 빠름)
평균 O(1), TreeMap은 O(log k)
메모리
낭비 큼
절약
적합한 상황
문자 종류 적고 고정 (a~z)
문자 종류 많음(유니코드/한글), 메모리 제한
시간 복잡도는 배열 버전과 동일 (모든 연산 O(M))
You can’t perform that action at this time.