Tech Stack/Java & Spring
[์ปฌ๋ ์ ํ๋ ์์ํฌ] ํด์(Hash)
_silver
2025. 4. 6. 10:11
์๋ฐ ์๋ฃ๊ตฌ์กฐ- ํด์(Hash) : ๋น ๋ฅธ ๋ฐ์ดํฐ ์กฐํ์ ์ค๋ณต ๋ฐฉ์ง ๊ฐ๋ฅ!
1. ๋ฆฌ์คํธ vs ์ (Set)
| ๊ตฌ์กฐ | ์์ | ์ค๋ณต | ํน์ง |
| List | O | O | ์ธ๋ฑ์ค ๊ธฐ๋ฐ, ์์ ์ ์ง |
| Set | X | X | ์ค๋ณต ์ ๊ฑฐ, ๋น ๋ฅธ ํ์ |
๋๋ณด๊ธฐ
List<String> cart = List.of("apple", "apple", "banana");
Set<String> ids = Set.of("user1", "user2"); // "user1" ์ค๋ณต ์ถ๊ฐ ๋ถ๊ฐ
2. Set ๊ตฌํ ์ฝ๋ ์์
โ๏ธ O(n)์ ์ ํ ํ์ -> ์ค๋ณต์ ์ ๋ง์ง๋ง ๋๋ฆฌ๋ค.
๋๋ณด๊ธฐ
// ๋ด๋ถ ๋ฐฐ์ด: ๊ณ ์ ํฌ๊ธฐ 10
private int[] elementData = new int[10];
private int size = 0;
// ์ค๋ณต ์์ด ๊ฐ ์ถ๊ฐ
public boolean add(int value) {
if (contains(value)) return false; // ์ด๋ฏธ ์กด์ฌํ๋ฉด ์ถ๊ฐ X
elementData[size++] = value; // ๋ฐฐ์ด์ ์ ์ฅ ํ size ์ฆ๊ฐ
return true;
}
// ํน์ ๊ฐ์ด ์๋์ง ํ์ธ
public boolean contains(int value) {
for (int data : elementData) {
if (data == value) return true; // ์ฐพ์ผ๋ฉด true ๋ฐํ
}
return false;
}
3. ํด์(Hash)์ ๋ฑ์ฅ
โ๏ธ ์ ํ ํ์ : O(n)์
int[] data = {1, 2, 5, 8};
int target = 8;
for (int i : data) {
if (i == target) return true;
}
โ๏ธ ์ธ๋ฑ์ค ๊ธฐ๋ฐ ์ ๊ทผ : O(1)
Integer[] hashArray = new Integer[10];
hashArray[8] = 8; // ๊ฐ์ด ๊ณง ์ธ๋ฑ์ค ์ญํ ์ ํจ
System.out.println(hashArray[8]); // ๊ฒฐ๊ณผ: 8
4. But,,,, ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น ์ฌํจ...
โ๏ธ ์) ๊ฐ์ ๋ฒ์๋ฅผ ๋๋ ค๋ณด๋ฉด?
- ๊ฐ์ ๋ช๊ฐ ์๋๋ฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ด ๋๋ฌด ์ปค์ ๋ญ๋น๊ฐ ์ฌํ๊ฒ ๋ฐ์ํ๊ฒ ๋จ
// ์ค์ ๋ก๋ ๋ช ๊ฐ๋ง ์ฐ๋๋ฐ ๋ฐฐ์ด์ 100์นธ
Integer[] inputArray = new Integer[100];
inputArray[99] = 99;
5. ํด์ ์ธ๋ฑ์ค(Hash Index) ๋ฐ๊ฒฌ
โ ๋๋จธ์ง ์ฐ์ฐ์ ํ์ฉํ์!
// ๋ฒ์๊ฐ ๋์ ๊ฐ์ ์ ํ๋ ๋ฐฐ์ด ๊ณต๊ฐ์ ํจ์จ์ ์ผ๋ก ๋งคํ์ด ๊ฐ๋ฅํ๋ค
int hashIndex = value % 10; // ํญ์ 0~9 ์ฌ์ด ๊ฐ๋ง ๋์ด
โ๏ธ ์ ์ฅ
int index = value % 10;
inputArray[index] = value; // ํด์ ์ธ๋ฑ์ค๋ฅผ ๋ฐฐ์ด ์ธ๋ฑ์ค๋ก ์ฌ์ฉ
โ๏ธ ์กฐํ
int result = inputArray[searchValue % 10]; // ํด์ ์ธ๋ฑ์ค๋ก ๋ฐ๋ก ์ ๊ทผ
6. ํด์ ์ถฉ๋์ ๋ฌธ์
// 99 % 10 = 9
// 9 % 10 = 9
// → ๋ ๋ค index 9์ ์ ์ฅ๋จ
๋๋ณด๊ธฐ
ํด๊ฒฐ๋ฐฉ๋ฒ : ๋ฐฐ์ด ์์ ๋ฆฌ์คํธ(๋ฒํท) ๋ฃ๊ธฐ
// ํฌ๊ธฐ 10์ง๋ฆฌ LinkedList ๋ฐฐ์ด
LinkedList<Integer>[] buckets = new LinkedList[10];
for (int i = 0; i < 10; i++) {
buckets[i] = new LinkedList<>(); // ๊ฐ ์ธ๋ฑ์ค์ ๋ฆฌ์คํธ ์ด๊ธฐํ
}
void add(LinkedList<Integer>[] buckets, int value) {
int index = value % 10;
if (!buckets[index].contains(value)) {
buckets[index].add(value);
}
}
7. ์ถฉ๋๊น์ง ๊ณ ๋ คํ HashSet ๊ตฌํ ์์
๋๋ณด๊ธฐ
static final int CAPACITY = 10;
public static void main(String[] args) {
// ํด์ ๋ฒํท ์ด๊ธฐํ
LinkedList<Integer>[] buckets = new LinkedList[CAPACITY];
for (int i = 0; i < CAPACITY; i++) {
buckets[i] = new LinkedList<>();
}
// ๊ฐ ์ถ๊ฐ (์ถฉ๋ ๊ณ ๋ ค)
add(buckets, 1);
add(buckets, 99); // 99 % 10 = 9 → ์ถฉ๋ ๋ฐ์
// ๊ฐ ๊ฒ์
int searchValue = 99;
boolean contains = contains(buckets, searchValue);
System.out.println(searchValue + " ์กด์ฌ ์ฌ๋ถ: " + contains);
}
โ๏ธ ๊ฐ ์ถ๊ฐ ๋ฉ์๋
private static void add(LinkedList<Integer>[] buckets, int value) {
int index = value % CAPACITY; // ํด์ ์ธ๋ฑ์ค ๊ณ์ฐ
LinkedList<Integer> bucket = buckets[index]; // ํด๋น ์ธ๋ฑ์ค์ ๋ฆฌ์คํธ ๊ฐ์ ธ์ค๊ธฐ
if (!bucket.contains(value)) { // ์ค๋ณต ๋ฐฉ์ง
bucket.add(value); // ๋ฆฌ์คํธ์ ๊ฐ ์ถ๊ฐ
}
}
โ๏ธ ๊ฐ ๊ฒ์ ๋ฉ์๋
private static boolean contains(LinkedList<Integer>[] buckets, int value) {
int index = value % CAPACITY; // ํด์ ์ธ๋ฑ์ค ๊ณ์ฐ
LinkedList<Integer> bucket = buckets[index]; // ๋ฆฌ์คํธ ๊ฐ์ ธ์ค๊ธฐ
return bucket.contains(value); // ๋ฆฌ์คํธ ๋ด๋ถ ํ์
}
8.Hash ์ฑ๋ฅ๊ณผ ์ถฉ๋ ํ๋ฅ
| ๋ฐฐ์ด ํฌ๊ธฐ(CAPACITY) | ์ถฉ๋ ๋ฐ์ ๊ฐ๋ฅ์ฑ |
| ์์ ์๋ก | ๋์ |
| ํด์๋ก | ๋ฎ์ |
โ๏ธ ์ถฉ๋ ์ค์ด๊ธฐ : ์ ์ ํ ๋ฐฐ์ด ํฌ๊ธฐ
โ๏ธ ์ผ๋ฐ์ ์ผ๋ก : ์ฌ์ฉ๋์ 75% ์ดํ๊ฐ ๋๋๋ก ์ค์
โ๏ธ ์ถ๋ ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ ์ํ๋ก ์ธํด ์ต์ ์ ๊ฒฝ์ฐ O(n) ๋ฐ์๋ ์ ์์
9. ์ ๋ฆฌ
| ํญ๋ชฉ | ํด์ ์ธ๋ฑ์ค ๋ฐฉ์ |
| ์ ์ฅ ์๋ | ํ๊ท O(1), ์ต์ O(n) |
| ์กฐํ ์๋ | ํ๊ท O(1), ์ต์ O(n) |
| ์ค๋ณต ํ์ฉ ์ฌ๋ถ | X (Set ๊ตฌ์กฐ ๊ธฐ์ค) |
| ๊ณต๊ฐ ํ์ฉ ํจ์จ์ฑ | ๋๋จธ์ง ์ฐ์ + ๋ฒํท์ผ๋ก ์ต์ ํ ๊ฐ๋ฅ |
| ์ถฉ๋ ํด๊ฒฐ | ๋ฒํท(๋ฆฌ์คํธ)์ ์ ์ฅ, contains()๋ก ํ์ธ |
<์ฐธ๊ณ > - ๊น์ํ์ ์ค์ ์๋ฐ ์ค๊ธ2ํธ ๊ฐ์ ์น์ 7. ์ปฌ๋ ์ ํ๋ ์์ํฌ ํด์(Hash)