๐Ÿ”‘ ํ•ด์‹œ ์ถฉ๋Œ(Hash Collision)๊ณผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์„ํ˜„ยท2025๋…„ 1์›” 31์ผ

Insight

๋ชฉ๋ก ๋ณด๊ธฐ
7/43

์˜ค๋Š˜์˜ ์ด์•ผ๊ธฐ

ํ•ด์‹œ ์ž๋ฃŒ ๊ตฌ์กฐ(Hash Data Structure)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํ”ผํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๊ฐ€ ํ•ด์‹œ ์ถฉ๋Œ(Hash Collision)์ž…๋‹ˆ๋‹ค. ํŒ€์›๋“ค๊ณผ ์˜ค์ „์— ๊ฐ™์ด ์ปคํ”ผ ๋งˆ์‹œ๋ฉด์„œ ํ•ด์‹œ ์ถฉ๋Œ ๊ด€๋ จํ•ด์„œ ์ด์•ผ๊ธฐ ํ–ˆ๋Š”๋ฐ ๋‚ด๊ฐ€ ์ •๋ง ์•„๋Š”๊ฑธ๊นŒ..? ํ•˜๋Š” ๋งˆ์Œ์ด ๋“ค์–ด ์ด๋ฒˆ ๊ธฐํšŒ์— ํ•ด์‹œ ์ถฉ๋Œ์˜ ๊ฐœ๋…๊ณผ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋ฒ•๋“ค์„ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


ํ•ด์‹œ ์ถฉ๋Œ์ด๋ž€? ๐Ÿค”

ํ•ด์‹œ ์ถฉ๋Œ์€ ์„œ๋กœ ๋‹ค๋ฅธ ํ‚ค๊ฐ€ ๋™์ผํ•œ ํ•ด์‹œ ๊ฐ’์„ ๊ฐ–๋Š” ํ˜„์ƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ•ด์‹œ ํ•จ์ˆ˜๋Š” ๋ฌดํ•œํ•œ ์ž…๋ ฅ ๊ณต๊ฐ„์„ ์œ ํ•œํ•œ ์ถœ๋ ฅ ๊ณต๊ฐ„(ํ•ด์‹œ ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ)์œผ๋กœ ๋งคํ•‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ถฉ๋Œ์€ ๋ถˆ๊ฐ€ํ”ผํ•ฉ๋‹ˆ๋‹ค.

ํ•ด์‹œ ์ถฉ๋Œ ์˜ˆ์‹œ

  1. ํ•ด์‹œ ํ•จ์ˆ˜ h(x) = x % 5 ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ:
    • h(10) = 10 % 5 = 0
    • h(15) = 15 % 5 = 0
    • h(20) = 20 % 5 = 0
  2. ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’(10, 15, 20)์ด ๊ฐ™์€ ํ•ด์‹œ ๊ฐ’(0)์„ ๊ฐ€์ง€๋ฏ€๋กœ ํ•ด์‹œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํ•ด์‹œ ์ถฉ๋Œ์„ ํ•ด๊ฒฐํ•˜์ง€ ์•Š์œผ๋ฉด, ํ•ด์‹œ ํ…Œ์ด๋ธ”์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


ํ•ด์‹œ ์ถฉ๋Œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ๐Ÿ› ๏ธ

ํ•ด์‹œ ์ถฉ๋Œ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐœ๋ฐฉ ์ฃผ์†Œ๋ฒ•(Open Addressing)๊ณผ ๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ•(Separate Chaining)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

1. ๊ฐœ๋ฐฉ ์ฃผ์†Œ๋ฒ•(Open Addressing) ๐Ÿ”„

๊ฐœ๋ฐฉ ์ฃผ์†Œ๋ฒ•์€ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ๋™์ผํ•œ ํ•ด์‹œ ํ…Œ์ด๋ธ” ๋‚ด์—์„œ ๋‹ค๋ฅธ ๋นˆ ๋ฒ„ํ‚ท์„ ์ฐพ์•„ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ฒ•๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค:

๐Ÿ“Œ ์„ ํ˜• ํƒ์‚ฌ๋ฒ•(Linear Probing)

์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•œ ์นธ์”ฉ ์ด๋™ํ•˜๋ฉฐ ๋นˆ ๊ณต๊ฐ„์„ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ (Java):

public class LinearProbingHashTable {
    private static final int SIZE = 10;
    private Integer[] table = new Integer[SIZE];

    public void insert(int key) {
        int index = key % SIZE;
        while (table[index] != null) {
            index = (index + 1) % SIZE; // ๋‹ค์Œ ์ธ๋ฑ์Šค๋กœ ์ด๋™
        }
        table[index] = key;
    }
}

โœ”๏ธ ์žฅ์ : ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ 
โš ๏ธ ๋‹จ์ : ํด๋Ÿฌ์Šคํ„ฐ๋ง(Clustering) ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์—ฐ์†๋œ ๋นˆ ๊ณต๊ฐ„์ด ์ค„์–ด๋“ค ์ˆ˜ ์žˆ์Œ

๐Ÿ“Œ ์ œ๊ณฑ ํƒ์‚ฌ๋ฒ•(Quadratic Probing)

์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ์ด๋™ ๊ฑฐ๋ฆฌ๋ฅผ ์ œ๊ณฑ์ˆ˜๋กœ ์ฆ๊ฐ€์‹œํ‚ค๋ฉฐ ๋นˆ ๊ณต๊ฐ„์„ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

ํƒ์‚ฌ ๋ฐฉ์‹ ์˜ˆ์‹œ:

  • ์ฒซ ๋ฒˆ์งธ ์ถฉ๋Œ: index + 1^2
  • ๋‘ ๋ฒˆ์งธ ์ถฉ๋Œ: index + 2^2
  • ์„ธ ๋ฒˆ์งธ ์ถฉ๋Œ: index + 3^2

โœ”๏ธ ์žฅ์ : ํด๋Ÿฌ์Šคํ„ฐ๋ง ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•  ์ˆ˜ ์žˆ์Œ
โš ๏ธ ๋‹จ์ : ํ…Œ์ด๋ธ” ํฌ๊ธฐ๊ฐ€ ์†Œ์ˆ˜(prime number)๊ฐ€ ์•„๋‹ˆ๋ฉด ์ถฉ๋Œ์ด ํ•ด๊ฒฐ๋˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Œ

๐Ÿ“Œ ์ด์ค‘ ํ•ด์‹ฑ(Double Hashing)

์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ณด์กฐ ํ•ด์‹œ ํ•จ์ˆ˜(Secondary Hash Function)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ํ•ด์‹œ ๊ฐ’์„ ๊ณ„์‚ฐํ•ด ๋นˆ ๊ณต๊ฐ„์„ ์ฐพ์Šต๋‹ˆ๋‹ค.

ํ•ด์‹œ ํ•จ์ˆ˜ ์˜ˆ์‹œ:

int h1(int key) { return key % SIZE; }
int h2(int key) { return 7 - (key % 7); }
  • ์ƒˆ๋กœ์šด ์ธ๋ฑ์Šค = (h1(key) + i * h2(key)) % SIZE

โœ”๏ธ ์žฅ์ : ํด๋Ÿฌ์Šคํ„ฐ๋ง ๋ฌธ์ œ๋ฅผ ์™„์ „ํžˆ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ
โš ๏ธ ๋‹จ์ : ์—ฐ์‚ฐ๋Ÿ‰์ด ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์Œ


2. ๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ•(Separate Chaining) ๐ŸŒ

๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ•์€ ๊ฐ ๋ฒ„ํ‚ท์„ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked List)๋กœ ๊ด€๋ฆฌํ•˜์—ฌ, ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ๋ฒ„ํ‚ท์˜ ๋ฆฌ์ŠคํŠธ์— ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ (Java):

import java.util.LinkedList;

public class SeparateChainingHashTable {
    private static final int SIZE = 10;
    private LinkedList<Integer>[] table = new LinkedList[SIZE];

    public SeparateChainingHashTable() {
        for (int i = 0; i < SIZE; i++) {
            table[i] = new LinkedList<>();
        }
    }

    public void insert(int key) {
        int index = key % SIZE;
        table[index].add(key);
    }
}

โœ”๏ธ ์žฅ์ : ํ•ด์‹œ ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ์— ์ œํ•œ์„ ๋ฐ›์ง€ ์•Š์œผ๋ฉฐ, ์ถฉ๋Œ ๋ฐœ์ƒ ์‹œ ํƒ์ƒ‰ ์‹œ๊ฐ„์ด ์ผ์ •
โš ๏ธ ๋‹จ์ : ๊ฐ ๋ฒ„ํ‚ท์ด ๋ฆฌ์ŠคํŠธ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€


โœ… ๊ฐœ๋ฐฉ ์ฃผ์†Œ๋ฒ• vs. ๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ• ๋น„๊ต

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์žฅ์ ๋‹จ์ 
์„ ํ˜• ํƒ์‚ฌ๋ฒ•๊ตฌํ˜„์ด ๊ฐ„๋‹จ, ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ ํด๋Ÿฌ์Šคํ„ฐ๋ง ๋ฌธ์ œ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
์ œ๊ณฑ ํƒ์‚ฌ๋ฒ•ํด๋Ÿฌ์Šคํ„ฐ๋ง ๋ฌธ์ œ ์™„ํ™” ๊ฐ€๋Šฅํ…Œ์ด๋ธ” ํฌ๊ธฐ ์ œ์•ฝ ์กด์žฌ
์ด์ค‘ ํ•ด์‹ฑํด๋Ÿฌ์Šคํ„ฐ๋ง ๋ฌธ์ œ ํ•ด๊ฒฐ์—ฐ์‚ฐ๋Ÿ‰ ์ฆ๊ฐ€ ๊ฐ€๋Šฅ
๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ•์œ ์—ฐํ•œ ์ถฉ๋Œ ํ•ด๊ฒฐ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ฆ๊ฐ€

๐Ÿš€ ์–ด๋–ค ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•ด์•ผ ํ• ๊นŒ?

  • ํ•ด์‹œ ํ…Œ์ด๋ธ”์ด ํฌ์ง€ ์•Š๊ณ , ์—ฐ์‚ฐ ์†๋„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค๋ฉด? โ†’ ๊ฐœ๋ฐฉ ์ฃผ์†Œ๋ฒ• (ํŠนํžˆ ์ด์ค‘ ํ•ด์‹ฑ) ์ถ”์ฒœ
  • ์ถฉ๋Œ์ด ๋งŽ์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๊ณ , ๋™์  ํ™•์žฅ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด? โ†’ ๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ• ์ถ”์ฒœ

๋งˆ์น˜๋ฉฐ ๐ŸŒŸ

ํ•ด์‹œ ์ถฉ๋Œ์€ ํ•ด์‹œ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํ”ผํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ์ง€๋งŒ, ์ ์ ˆํ•œ ์ถฉ๋Œ ํ•ด๊ฒฐ ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ฐœ๋ฐฉ ์ฃผ์†Œ๋ฒ•(์„ ํ˜• ํƒ์‚ฌ, ์ œ๊ณฑ ํƒ์‚ฌ, ์ด์ค‘ ํ•ด์‹ฑ) ๋˜๋Š” ๋ถ„๋ฆฌ ์—ฐ๊ฒฐ๋ฒ•์„ ์„ ํƒํ•˜์—ฌ ์ ์ ˆํžˆ ํ™œ์šฉํ•ด๋ณด์„ธ์š”! ๐Ÿš€


0๊ฐœ์˜ ๋Œ“๊ธ€