도구스개발

k-d 트리 최근접 이웃 탐색 계산기

평면 위의 점들을 x·y 축을 번갈아 가며 트리로 쌓고 질의점에서 가장 가까운 점을 찾습니다. 가지치기로 몇 개를 건너뛰었는지 세어 전수 탐색과 나란히 놓고, 답이 같은지도 매번 확인합니다.

x와 y를 짝지어 넣습니다. 쉼표·공백·줄바꿈 아무것으로나 나눠도 됩니다. 400개까지 다룹니다.

가장 가까운 점

(38, 51)

거리 8.062입니다. 점 30개 중 12개만 들여다봤습니다 — 전수 탐색보다 60% 적게 봤습니다.

점 개수30
트리 높이5
최근접 거리8.0623
들여다본 노드12
가지치기로 버린 노드18
전수 탐색이었다면30
전수 탐색과 답 대조같음

평면이 갈라진 모습

선 하나가 노드 하나입니다. 깊이 0은 세로선(x로 가름), 깊이 1은 가로선(y로 가름)으로 번갈아 갑니다. 붉은 십자가 질의점, 파란 점이 답이고, 점선 원 안에는 다른 점이 하나도 없습니다 — 이 원이 가지치기의 기준입니다.

탐색 기록

순서노드거리분할선까지반대편
1(42, 46) · x로 가름120
2(50, 61) · y로 가름8.543
3(86, 7) · x로 가름67.3644버림
4(51, 32) · y로 가름27.5126버림
5(74, 40) · x로 가름36.7232
6(70, 96) · x로 가름47.228버림
7(62, 95) · y로 가름42.0637버림
8(63, 76) · x로 가름27.6621
9(19, 45) · y로 가름26.4213버림
10(29, 72) · x로 가름19.113버림
11(34, 77) · y로 가름20.6219버림
12(38, 51) · x로 가름8.064

★ 표시가 그 노드에서 최선이 갱신된 자리입니다. 「반대편」이 이 자료구조의 전부입니다 — 분할선까지의 거리가 지금까지 찾은 최선보다 멀면 반대편에는 더 가까운 점이 있을 수 없으니 통째로 버립니다. 가까우면 반드시 봐야 하고, 이 판정을 빠뜨리면 대개는 맞지만 가끔 틀린 답이 나옵니다.

2차원에서는 이렇게 이득이 나지만 차원이 올라가면 가지치기가 듣지 않습니다. 차원이 d일 때 반대편을 확인해야 하는 축이 d개로 늘어 대부분의 가지가 살아남기 때문입니다. 점 개수가 2^d보다 훨씬 많지 않으면 전수 탐색보다 나을 것이 없고, 그래서 고차원에서는 근사 최근접 방법으로 넘어갑니다.

사용 방법

  1. 1점 목록을 넣습니다. 예제 버튼으로 무작위 점을 뿌려 볼 수 있습니다.
  2. 2질의점의 x·y를 넣습니다.
  3. 3「평면이 갈라진 모습」에서 세로선과 가로선이 번갈아 나오는 것을 확인합니다.
  4. 4들여다본 노드 수를 전수 탐색과 견줍니다.
  5. 5「탐색 기록」의 「반대편」 열에서 어느 가지를 버렸고 어느 가지를 봤는지 확인합니다.

자주 묻는 질문

평면(또는 공간)의 점들을 축을 번갈아 가며 갈라 쌓는 이진 트리입니다. 깊이 0에서는 x 좌표의 중앙값으로 좌우를 나누고, 깊이 1에서는 y 좌표로, 깊이 2에서는 다시 x로 나눕니다. 노드 하나가 점 하나이면서 그 점을 지나는 분할선이기도 합니다. 중앙값으로 가르므로 트리 높이가 log₂n으로 눌립니다.

분할선까지의 거리를 지금까지 찾은 최선 거리와 견줍니다. 질의점에서 분할선까지의 거리가 최선보다 멀면, 반대편의 어떤 점이든 적어도 분할선을 넘어야 하므로 최선보다 가까울 수 없습니다. 그러면 그 가지를 통째로 버립니다. 반대로 분할선이 최선보다 가까우면 반대편에 더 가까운 점이 있을 수 있으므로 반드시 봐야 합니다.

가끔 틀린 답이 나옵니다. 이것이 k-d 트리 구현에서 가장 흔한 버그이고, 무서운 점은 대부분의 입력에서는 맞는 답이 나온다는 것입니다. 질의점이 분할선 가까이 있을 때만 어긋나므로 몇 번 돌려 보고 「잘 되네」 하고 넘어가기 쉽습니다. 이 계산기는 답을 낼 때마다 전수 탐색과 대조한 결과를 함께 보여 줍니다.

2차원에서 점이 고르게 흩어져 있으면 평균 O(log n)입니다. 점 400개에서 대개 스무 개 안팎만 보고 끝납니다. 다만 최악의 경우는 여전히 O(n)이고, 점이 한 직선 위에 몰려 있거나 질의점이 아주 멀리 있으면 이득이 크게 줄어듭니다. 예제의 「한 줄로 몰린 점」으로 확인할 수 있습니다.

차원이 올라가면 가지치기가 듣지 않는 현상입니다. 차원 d에서는 반대편을 확인해야 하는 축이 d개로 늘어 대부분의 가지가 살아남고, 결국 거의 모든 점을 보게 됩니다. 점 개수가 2^d보다 훨씬 많지 않으면 전수 탐색보다 나을 것이 없다는 것이 경험칙이라, 수백 차원인 임베딩 벡터 검색에는 쓰지 않고 근사 최근접(HNSW·LSH)으로 갑니다.

가르는 방식이 다릅니다. k-d 트리는 «점 하나»를 골라 그 점을 지나는 선으로 한 번에 둘로 나누고 축을 번갈아 씁니다. 쿼드트리는 «구역 한가운데»를 기준으로 한 번에 넷으로 나눕니다. k-d 트리는 점 분포에 맞춰 균형이 잡히고, 쿼드트리는 좌표만 보면 어느 칸인지 알 수 있어 삽입·삭제가 쉽습니다.

전송되지 않습니다. 트리를 쌓고 탐색하는 일이 모두 브라우저 안에서 이뤄지고, 입력값은 이 기기에만 남습니다.

알아두면 좋은 점

  • 정답지는 가지치기를 전혀 하지 않는 전수 탐색입니다. 무작위 점 1~60개와 무작위 질의점으로 2,000번 돌려 두 방법의 답이 모두 같은지 확인했습니다. 화면에도 매번 대조 결과를 함께 보여 줍니다.
  • 가지치기 판정이 장식이 아닌지도 확인했습니다. 「내려간 쪽만 보는」 탐색을 따로 만들어 300번 돌려 보니 실제로 틀린 답이 나오는 경우가 있었습니다. 통과만 보면 판정을 지워도 알아채지 못하기 때문에 넣은 검사입니다.
  • 트리 구조도 검사합니다. 노드 수가 점 개수와 같은지, 모든 점이 정확히 한 번씩 들어가는지, 축이 깊이에 따라 번갈아 쓰이는지, 왼쪽 부분나무의 좌표가 분할 축에서 노드보다 크지 않은지, 높이가 ⌈log₂(n+1)⌉을 넘지 않는지를 봅니다.
  • 가지치기의 이득도 값으로 확인했습니다. 점이 16 → 64 → 256 → 400개로 늘 때 전수 탐색 대비 보는 비율이 계속 낮아지고, 400개에서는 30% 아래로 떨어집니다.
  • 겹친 점, 한 직선 위의 점, 질의점이 아주 멀리 있는 경우도 함께 확인했습니다.
  • 2차원만 다룹니다. 400개까지 넣을 수 있습니다.
  • 같은 거리의 점이 여럿이면 어느 것을 골라도 옳으므로, 전수 탐색과의 대조는 점이 아니라 거리로 합니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.