| ์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- ์๋ฃ๊ตฌ์กฐ
- ์ปดํจํฐ ๊ณตํ
- TestCode
- ๋ฐฑ์๋๊ณต๋ถ
- ํ๋ก๊ทธ๋๋จธ์ค
- spring boot
- ์ปดํจํฐ ๊ตฌ์กฐ
- array
- ๋ฐฑ์๋
- ORM
- ์ฐ๊ด๊ด๊ณ
- ๋ฐฑ์ค
- ํต์ฌ๊ฐ์ด๋
- error
- JPA
- LinkedList
- restTemplate
- spring
- ์๋ฒ
- SpringBoot
- JWT
- actuator
- ์ ๋ก๋ฒ ์ด์ค
- queue
- ๋ฐฑ์๋์ค์ฟจ
- SpringSecurity
- QueryDSL
- ์คํ๋ง๋ถํธ
- ๊ฐ๋ฐ์
- Java
- Today
- Total
be_better
[์๋ฃ๊ตฌ์กฐ] ํธ๋ผ์ด (Trie) ๋ณธ๋ฌธ
๋ชฉ์ฐจ
๐ ํธ๋ผ์ด (Trie)
๋ฌธ์์ด์ ์ ์ฅํ๊ณ ๋น ๋ฅด๊ฒ ํ์ํ๊ธฐ ์ํ ํธ๋ฆฌ ํํ์ ์๋ฃ๊ตฌ์กฐ
๋๋์ค ํธ๋ฆฌ(Radix tree), ์ ๋์ฌ ํธ๋ฆฌ(Prefix tree), ํ์ ํธ๋ฆฌ(Retrieval tree) ๋ฑ์ผ๋ก ๋ถ๋ฆฌ๋ฉฐ
Trie๋ Retrieval tree์์ ํ์๋ ๋จ์ด๋ค.
๊ธฐ๋ณธ ๊ตฌ์กฐ
๋ฌธ์์ด ์งํฉ {"apple", "app", "agree", "eight", "elephant", "zero"} ์ ํธ๋ผ์ด๋ก ์ง์ ๊ตฌํ

์ฅ์
๋ฌธ์์ด์ ๋น ๋ฅด๊ฒ ํ์ ํ ์ ์๋ค.
๋จ์
ํ์ํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํฌ๋ค๋ ๋จ์
์ด ๋ฉ๋ชจ๋ฆฌ๋ O(ํฌ์ธํฐ์ ํฌ๊ธฐ * ํฌ์ธํฐ ๋ฐฐ์ด์ ๊ฐ์ * ์ด ๋ ธ๋์ ๊ฐ์) ๋งํผ ํ์
๋จ์ ์ ๋ณด์ํ๊ธฐ ์ํด map ์ด๋ vector ์ ์ฌ์ฉํด ํ์ํ ๋ ธ๋๋ง ๋ฉ๋ชจ๋ฆฌ์ ํ ๋นํ๋ ๋ฐฉ์ ์ฑํ
๐ฆ ํธ๋ผ์ด์ ์ฌ์ฉ์ฌ๋ก
- ์๋์์ฑ ๊ธฐ๋ฅ
- ์ฌ์ ๊ฒ์
โ๐ป ํธ๋ผ์ด ADT (์ถ์ ๋ฐ์ดํฐ ํ์ )
| create() | ํธ๋ผ์ด ์์ฑ | |
| insert(str) | ๋ฌธ์์ด ์ฝ์ | |
| delete(str) | ๋ฌธ์์ด ์ญ์ | |
| search(str) | ๋ฌธ์์ด ํ์ | |
โ๏ธ ํธ๋ผ์ด ๊ธฐ๋ฅ & ๋์์๋ฆฌ
ํธ๋ผ์ด ๋ ธ๋ ์์ฑ
- ๋ฌธ์์ด์ ์ด๋ฃจ๋ ์ํ๋ฒณ, ๋ค์ ๋ ธ๋ ์์ Map ๊ณผ
- ํ์ฌ ๋ ธ๋๊ฐ ๋ฌธ์์ด์ ๋ ๋ ธ๋์ธ์ง ํ์ธํ๊ธฐ ์ํ boolean ํ์ ์ isTerminal๋ฅผ ๋ฉค๋ฒ๋ก ๊ฐ๋ ํด๋์ค ์์ฑ
class Node {
HashMap<Character, Node> child;
boolean isTerminal;
public Node() {
this.child = new HashMap<>();
this.isTerminal = false;
}
}
๋ฌธ์์ด ์ฝ์
- ์๋ฌด๊ฒ๋ ๋ค์ด์์ง ์์ root๋ถํฐ ์์
- ๋ฌธ์์ด์ ์์์๋ถํฐ ์ชผ๊ฐ๋ฉด์ ๋ฌธ์๋ฅผ ํ๋์ฉ ํ์ธ
- ์ด๋ฏธ ์๋ ๋ฌธ์๋ผ๋ฉด ๋ค์ ๋ ธ๋๋ก ์ด๋
- ์ด๋ฏธ ์๋ ๋ฌธ์๊ฐ ์๋๋ผ๋ฉด ์๋ก์ด ๋ ธ๋ ์ถ๊ฐ
- ๋ฌธ์์ด ๋ ๋ฌธ์๊น์ง ๋ฃ์๋ค๋ฉด ๊ทธ ๋ ธ๋์ isTerminal = true๋ก ๋ฐ๊ฟ์ฃผ๊ณ return
// ์๋ ์ฝ๋
Node root;
public Trie() {
this.root = new Node();
}
public void insert(String str) {
Node cur = this.root;
for (i = 0; str ๋๊น์ง) {
Character c = str.charAt(i);
if (์ด๋ฏธ ์๋ ๋ฌธ์๊ฐ ์๋๋ฉด) {
cur.child.put(c, new Node()); // ์๋ก์ด ๋
ธ๋ ์์ฑ
} else (์ด๋ฏธ ์๋ ๋ฌธ์๋ผ๋ฉด) {
cur = cur.child.get(c); // ๋ค์ ๋
ธ๋๋ก ์ด๋
}
if (str ๋๊น์ง ๋ค ๋ฃ์๋ค๋ฉด) {
isTerminal = true;
return;
}
}
}
๋ฌธ์์ด ์ญ์
- ๋ฌธ์๋ฅผ ํ๋์ฉ ๋น๊ต
- ์ฐพ์ผ๋ ค๋ ๋ฌธ์๊ฐ ์๋์ง ํ์ธ ํ ์์ผ๋ฉด false ๋ฆฌํด
- ๋ค์ ๋ ธ๋๋ฅผ ํ์ธํ๊ธฐ ์ํด index์ฆ๊ฐ
- ์ฆ๊ฐํ index์ ๋ํด ๋ฌธ์์ด์ ๊ธธ์ด์ ๊ฐ์์ก์ง๋ง isTerminal์ด true๊ฐ ์๋๋ผ๋ฉด false ๋ฆฌํด
- true๋ผ๋ฉด ์ฐพ์ผ๋ ค๋ ๋ฌธ์์ด์ด๊ธฐ ๋๋ฌธ์ ์ญ์ ๋ฅผ ์ํด isTerminal์ false๋ก ๋จผ์ ๋ฐ๊ฟ์ค
- ๋ค์ ๋ ธ๋๊ฐ ์๋ค๋ฉด ํ์ฌ ๋ ธ๋ ์ญ์
- ๋ฌธ์์ด์ ๊ธธ์ด์ ์์ง ๊ฐ์ง ์์ ๋ ธ๋์ ๋ํด์๋ ์ฌ๊ทํจ์ ์ด์ฉ
- ์ฌ๊ทํจ์์ ๊ฒฐ๊ณผ๊ฐ false๋ผ๋ฉด false ๋ฆฌํด
// ์๋ ์ฝ๋
public boolean delete(Node node, String str, int index) {
Character c = str.charAt(index);
if (๋ฌธ์๊ฐ ํฌํจ๋์ด ์์ง ์๋๋ค๋ฉด) {
return false;
}
Node cur = node.child.get(c); // ๋ค์ ๋
ธ๋ ์ ์ฅ
index ํ๋ ์ฆ๊ฐ;
if (index๊ฐ ๋ฌธ์์ด์ ๊ธธ์ด์ ๊ฐ๋ค๋ฉด) {
if (isTerminal์ด false๋ผ๋ฉด) {
return false;
}
์ง์ฐ๊ธฐ ์ ์ isTerminal false๋ก ๋ฐ๊ฟ;
if (๋ค์ ๋
ธ๋๊ฐ ์๋๊ฒ ๋ง๋ค๋ฉด) {
ํ์ฌ ๋
ธ๋ remove;
}
} else (index๊ฐ ์์ง ๋ฌธ์์ด์ ๋๊น์ง ์๊ฐ์ผ๋ฉด) {
if (delete(cur, str, index)๊ฐ false๋ผ๋ฉด) {
return false;
}
if (isTerminal์ด false์ด๊ณ , ๋ค์ ๋
ธ๋๊ฐ ์๋๊ฒ ๋ง๋ค๋ฉด) {
ํ์ฌ ๋
ธ๋ remove;
}
}
return true;
}
โฑ๏ธ ํธ๋ผ์ด์ ์๊ฐ๋ณต์ก๋
์ ์ผ ๊ธด ๋ฌธ์์ด์ ๊ธธ์ด๋ฅผ N, ์ด ๋ฌธ์์ด์ ์๋ฅผ M์ด๋ผ๊ณ ํ ๋,
- ์์ฑ O(N*M)
- ํ์ O(N)
- ์ฝ์ ๋ง O(N)
์์ฑ์ ๊ฐ์ฅ ๊ธด ๋ฌธ์์ด์ ๊ธธ์ด N์ M๋งํผ ๋ฃ์ด์ผ ํ๋ O(N*M)
ํ์์ ๊ฐ์ฅ ๊ธด ๋ฌธ์์ด์ ๊ธธ์ด๋งํผ๋ง ํ์ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ O(N)
์ฝ์ ์ ๋ฌธ์์ด์ ๋ฌธ์ ํ๋์ฉ ๋ฃ์ผ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ๊ธด ๋ฌธ์์ด์ ๊ธธ์ด N๋งํผ์ O(N)
'์๋ฃ๊ตฌ์กฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [์๋ฃ๊ตฌ์กฐ] ๋ฐฐ์ด (Array) (0) | 2023.08.10 |
|---|---|
| [์๋ฃ๊ตฌ์กฐ] ํ (Queue) (0) | 2023.08.10 |
| [์๋ฃ๊ตฌ์กฐ] ์คํ (Stack) (0) | 2023.08.10 |