1. ํŠธ๋ผ์ด(Trie)๋ž€?

์›ํ•˜๋Š” ์š”์†Œ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•ด ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ด์ง„ ๊ฒ€์ƒ‰ ํŠธ๋ฆฌ ๋“ฑ์—์„œ๋Š” ํƒ€๊ฒŸ ์š”์†Œ๋ฅผ ์ฐพ๋Š”๋ฐ์— O(logN)์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋ฌธ์ž์—ด์˜ ๊ฒฝ์šฐ ๋‘ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๋งŒํผ์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—,
์›ํ•˜๋Š” ๋ฌธ์ž์—ด์„ ์ฐพ๊ธฐ ์œ„ํ•ด์„œ๋Š” O(MlogN)์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ด ์ž‘์—…์„ ์—ฌ๋Ÿฌ๋ฒˆ ์ˆ˜ํ–‰ํ•œ๋‹ค๋ฉด ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 
์ด๋Ÿฌํ•œ ๋ฌธ์ž์—ด ๊ฒ€์ƒ‰์‹œ์˜ ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ํŠธ๋ผ์ด(Trie)์ž…๋‹ˆ๋‹ค.

 

  • ํŠธ๋ผ์ด(Trie)๋Š” ๋ฌธ์ž์—ด์„ ์ €์žฅํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ํŠธ๋ฆฌ ํ˜•ํƒœ์˜ ์ž๋ฃŒ๊ตฌ์กฐ
  • ๊ตฌ๊ธ€์ด๋‚˜ ๋„ค์ด๋ฒ„ ๋“ฑ์— ๊ฒ€์ƒ‰์–ด๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ, ์‚ฌ์ „ ๊ฒ€์ƒ‰ ๋“ฑ ๋ฌธ์ž์—ด์„ ํƒ์ƒ‰ํ•˜๋Š”๋ฐ ํŠนํ™”๋˜์–ด์žˆ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ž˜๋”•์Šค ํŠธ๋ฆฌ(Radix Tree)๋‚˜ ์ ‘๋‘์‚ฌ ํŠธ๋ฆฌ(Prefix Tree), ํƒ์ƒ‰ ํŠธ๋ฆฌ(Retrieval Tree)๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค
    • ํŠธ๋ผ์ด(Trie)๋Š” Retrieval Tree์—์„œ ๋‚˜์˜จ ๋‹จ์–ด

์˜ˆ๋ฅผ ๋“ค์–ด 'Tistory'๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ์ œ์ผ ๋จผ์ € 'T'๋ฅผ ์ฐพ๊ณ , ๋‹ค์Œ์— 'i', 's', 't', ... ์˜ ์ˆœ๋Œ€๋กœ ์ฐพ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๊ฐœ๋…์„ ์ ์šฉํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ํŠธ๋ผ์ด(Trie)์ž…๋‹ˆ๋‹ค.

 

2. ํŠธ๋ผ์ด(Trie)์˜ ์ž‘๋™ ์›๋ฆฌ

๋‹ค์Œ ๊ทธ๋ฆผ์€ ๋ฌธ์ž์—ด ์ง‘ํ•ฉ {"apple", "app", "dad", "dream", "age"}๋ฅผ ํŠธ๋ผ์ด๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

*ํŠธ๋ผ์ด(Trie)๋Š” ์ง‘ํ•ฉ์— ํฌํ•จ๋œ ๋ฌธ์ž์—ด์˜ ์ ‘๋‘์‚ฌ๋“ค์— ๋Œ€์‘๋˜๋Š” ๋…ธ๋“œ๋“ค์ด ์„œ๋กœ ์—ฐ๊ฒฐ๋œ ํŠธ๋ฆฌ์ž…๋‹ˆ๋‹ค.

 

[๊ณตํ†ต ์ ‘๋‘์–ด]

"apple"๊ณผ "app"์€ "app"๋ผ๋Š” ๊ณตํ†ต ์ ‘๋‘์–ด๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ™์€ ์„œ๋ธŒ ํŠธ๋ฆฌ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ฆ‰, "a"๋ผ๋Š” ๊ณตํ†ต ์ ‘๋‘์–ด๋ฅผ ๊ฐ€์ง„ "apple", "app", "age"๋Š” Head์˜ ์ž์‹ ๋…ธ๋“œ 'a'์—,

"d"๋ผ๋Š” ๊ณตํ†ต ์ ‘๋‘์–ด๋ฅผ ๊ฐ€์ง„ "dad", "dream"์€ Head์˜ ์ž์‹ ๋…ธ๋“œ 'd'์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

 

[Leaf Node]

๋ฆฌํ”„ ๋…ธ๋“œ๋Š” ๊ฐ ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž๋ฅผ ์˜๋ฏธํ•˜๋ฏ€๋กœ, ๋‹จ์–ด์˜ ๋ ๋ฌธ์ž๋ผ๋Š” ํ‘œ์‹œ(endOfWord)๋ฅผ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ฆฌํ”„ ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” ๋‹จ์–ด์˜ ๊ฐœ์ˆ˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

[ํŠธ๋ผ์ด(Trie) ์ƒ์„ฑ ๊ณผ์ •]

1. "apple"๋ฅผ ํŠธ๋ผ์ด์— ์‚ฝ์ž…

  • 'a': ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž์ธ 'a'๋Š” ์ดˆ๊ธฐ์— ํŠธ๋ผ์ด ์ž๋ฃŒ๊ตฌ์กฐ ๋‚ด์— ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฏ€๋กœ Head์˜ ์ž์‹๋…ธ๋“œ์— 'a'๋ฅผ ์ถ”๊ฐ€
  • 'p': 'a' ๋…ธ๋“œ์—๋„ ํ˜„์žฌ ์ž์‹์ด ํ•˜๋‚˜๋„ ์—†์œผ๋ฏ€๋กœ 'a'์˜ ์ž์‹๋…ธ๋“œ์— 'p'๋ฅผ ์ถ”๊ฐ€
  • 'p', 'l', 'e'์— ๋Œ€ํ•ด์„œ๋„ ์ž์‹๋…ธ๋“œ๋กœ ์ถ”๊ฐ€
  • 'l': "apple" ๋‹จ์–ด๊ฐ€ ๋๋‚จ์„ ์•Œ๊ธฐ ์œ„ํ•ด 'l' ๋…ธ๋“œ์— ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ(endOfWord)์ž„์„ ํ‘œ์‹œ

2. "app"๋ฅผ ํŠธ๋ผ์ด์— ์‚ฝ์ž…

  • 'a': ํ˜„์žฌ Head์˜ ์ž์‹ ๋…ธ๋“œ๋กœ 'a'๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— 'a' ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ์กด์— ์žˆ๋Š” 'a'๋…ธ๋“œ๋กœ ์ด๋™
  • 'p': 'p'๋„ 'a'์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์žˆ์œผ๋ฏ€๋กœ 'p'๋กœ ์ด๋™
  • 'p': 'p'๋„ 'a'์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์žˆ์œผ๋ฏ€๋กœ 'p'๋กœ ์ด๋™ํ•˜๋ฉด์„œ, 'p'๋…ธ๋“œ์— ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์ž„์„ ํ‘œ์‹œ

3. "dad", "dream",  "age"๋ฅผ ํŠธ๋ผ์ด์— ์‚ฝ์ž…

  • "dad"์™€ "dream"์˜ ์ฒซ ๋ฌธ์ž์ธ 'd'๋Š” Head์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€ํ•ด์„œ, ๊ฐ ๋‹จ์–ด๋ณ„๋กœ ๋ฌธ์ž๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ถ”๊ฐ€
  • "age"๋Š” Head์˜ ์ž์‹ ๋…ธ๋“œ๋กœ 'a'๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—,
    • 'a'๋กœ ์ด๋™ => 'a'์˜ ์ž์‹ ๋…ธ๋“œ์— 'g'๊ฐ€ ์—†์œผ๋ฏ€๋กœ 'g'๋ฅผ ์ถ”๊ฐ€ => 'e'๋„ 'g'์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์ถ”๊ฐ€ํ•œ ํ›„ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ํ‘œ์‹œ

 

3. ํŠธ๋ผ์ด(Trie) ๊ตฌํ˜„(Java)

๊ทธ๋Ÿผ ํŠธ๋ผ์ด๋ฅผ Java๋กœ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Map Interface๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

Map์˜ Key๊ฐ’์—๋Š” ๋‹จ์–ด๋ฅผ ์ด๋ฃจ๋Š” ๊ฐ๊ฐ์˜ ๋ฌธ์ž๋“ค์ด ๋“ค์–ด๊ฐ€๊ณ , Value์—๋Š” ์ž์‹ ๋…ธ๋“œ ํด๋ž˜์Šค๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ์ˆœ์ฐจ์ ์œผ๋กœ ์ž๋ฐ”๋กœ ๊ตฌํ˜„์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Node ํด๋ž˜์Šค ์ƒ์„ฑ

Node ํด๋ž˜์Šค๋Š” ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ์ •๋ณด์™€ ๋‹จ์–ด์˜ ๋์ธ์ง€๋ฅผ ํŒ๋‹จํ•˜๋Š” ๋ณ€์ˆ˜๋กœ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

private class Node {
    HashMap<Character, Node> childNode = new HashMap<>(); // ์ž์‹ ๋…ธ๋“œ
    boolean endOfWord; // ๋‹จ์–ด์˜ ๋์ธ์ง€์— ๋Œ€ํ•œ ํ”Œ๋ž˜๊ทธ
}

 

ํŠธ๋ผ์ด(Trie) ์ž๋ฃŒ๊ตฌ์กฐ ํด๋ž˜์Šค ์ƒ์„ฑ

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด ์ค๋‹ˆ๋‹ค.

*๋ฃจํŠธ ๋…ธ๋“œ๋Š” 1) ํ•ญ์ƒ ๋น„์–ด์žˆ๊ณ  2) ๋ฃจํŠธ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๋Š” ๊ฐ ๋‹จ์–ด์˜ ์ฒซ ๊ธ€์ž์ž…๋‹ˆ๋‹ค.

public class Trie {
    private Node rootNode;
    Trie() {
        // Trie ์ƒ์„ฑ์‹œ ๋ฃจํŠธ ๋…ธ๋“œ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ์ƒ์„ฑ
        rootNode = new Node(); // ๋ฃจํŠธ ๋…ธ๋“œ๋Š” ๋นˆ ๋…ธ๋“œ
    }
}

 

๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ

1) ๋…ธ๋“œ ์ถ”๊ฐ€(insert)

์ž…๋ ฅ ๋ฐ›์€ ๋‹จ์–ด๋ฅผ ๋ฌธ์ž ์ˆœ๋Œ€๋กœ ํŠธ๋ฆฌ ๊ณ„์ธต ๊ตฌ์กฐ์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์ƒ์„ฑํ•ด์„œ ๋„ฃ์Šต๋‹ˆ๋‹ค.

  • ๋ฌธ์ž๊ฐ€ ์ž์‹ ๋…ธ๋“œ์— ์กด์žฌํ•˜๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ž์‹ ๋…ธ๋“œ๋กœ ์ด๋™
  • ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์ธ ๋…ธ๋“œ๋ผ๋ฉด endOfWord = true๋กœ ์„ค์ •
public void insert(String word) {
    Node node = this.rootNode;
    // ๋‹จ์–ด์˜ ๋ฌธ์ž๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ์ž์‹ ๋…ธ๋“œ๋ฅผ ํ™•์ธ
    //  1) ์ž์‹ ๋…ธ๋“œ์— ์žˆ๋Š” ๋ฌธ์ž๋ผ๋ฉด ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ด
    //  2) ์ž์‹ ๋…ธ๋“œ์— ์—†๋Š” ๋ฌธ์ž๋ผ๋ฉด ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ
    for (int i=0; i<word.length(); i++) node = node.childNode.computeIfAbsent(word.charAt(i), key -> new Node());
    node.endOfWord = true; // ๋‹จ์–ด(word)์˜ ๋ฌธ์ž๋ฅผ ๋ชจ๋‘ ์ˆœํšŒํ•˜๋ฉด ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋Š” ๋ฆฌํ”„ ๋…ธ๋“œ(=๋งˆ์ง€๋ง‰ ๋ฌธ์ž)์ด๊ธฐ๋•Œ๋ฌธ์— endOfWord๋ฅผ true๋กœ ์„ค์ •
}

 

2) ํฌํ•จ ์—ฌ๋ถ€ ํ™•์ธ(contains)

ํŠน์ • ๋‹จ์–ด๊ฐ€ ํŠธ๋ผ์ด์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ๋‹จ์–ด์˜ ๋ฌธ์ž ์ˆœ๋Œ€๋กœ ์ผ์น˜ํ•˜๋Š” ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๊ณ„์ธต์„ ์ด๋ฃจ๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ
  • ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์— endOfWord๊ฐ€ true

๋‘ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ํŠธ๋ผ์ด์— ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

public boolean contains(String word) {
    Node node = this.rootNode;
    char c;
    for (int i=0; i<word.length(); i++) {
        c = word.charAt(i);
        if (!node.childNode.containsKey(c)) return false; // ํ˜„์žฌ ํƒ์ƒ‰ํ•˜๋Š” ๋ฌธ์ž๊ฐ€ ์ž์‹ ๋…ธ๋“œ์— ์—†๋‹ค๋ฉด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋‹จ์–ด
        node = node.childNode.get(c); // ๋งˆ์ง€๋ง‰ ๋ฌธ์ž๋ฅผ node์— ์ €์žฅ
    }
    return node.endOfWord; // ๋งˆ์ง€๋ง‰ ๋ฌธ์ž ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
}

 

3) ๋…ธ๋“œ ์‚ญ์ œ(delete)

ํŠธ๋ผ์ด์— ์ถ”๊ฐ€ํ–ˆ๋˜ ๋‹จ์–ด๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

  • ๋ถ€๋ชจ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‚ญ์ œํ•  ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž๊นŒ์ง€ ์ด๋™ํ•ด์„œ ๋ฌธ์ž๋ฅผ ์‚ญ์ œํ•ด์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. => ์žฌ๊ท€
  • ๋‹ค์Œ ๋ฌธ์ž์— ์กด์žฌํ•˜๋Š” ์ž์‹๋…ธ๋“œ๊ฐ€ ์žˆ๊ณ , ์‚ญ์ œ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ(๋ฆฌํ”„ ๋…ธ๋“œ)์—๋Š” endOfWord๊ฐ€ true๋กœ ๋˜์–ด์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 
    • ์ฆ‰, ์‚ญ์ œํ•  ๋‹จ์–ด๊ฐ€ ํŠธ๋ผ์ด์— ํฌํ•จ๋˜์–ด์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์–ด ์‚ญ์ œ๋ฅผ ์œ„ํ•ด ๋งˆ์ง€๋ง‰ ๋ฌธ์ž ๋…ธ๋“œ์ธ ๋ฆฌํ”„ ๋…ธ๋“œ์˜ endOfWord๋ฅผ false๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฑฐ๊พธ๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ๋‹จ, ์•„๋ž˜ ๋‘ ์กฐ๊ฑด์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
    • ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ž์‹๋…ธ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ
      • ์ž์‹๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋Š” ๋œป์€ ๋‹ค๋ฅธ ๋‹จ์–ด์— ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ž๋ผ๋Š” ๋œป์ด๋ฏ€๋กœ ์‚ญ์ œํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.
    • endOfWord๊ฐ€ true์ธ ๊ฒฝ์šฐ
      • ๋‹จ์–ด์˜ ๋์ธ ๋ฌธ์ž์ธ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ๋‹จ์–ด์— ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ž๋ผ๋Š” ๋œป์ด๋ฏ€๋กœ ์‚ญ์ œํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.
public void delete(String word) {
    delete(this.rootNode, word, 0);
}
// ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์œ„ํ•œ ํ•จ์ˆ˜ ์˜ค๋ฒ„๋กœ๋”ฉ
private void delete(Node node, String word, int idx) {
    // ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค์ธ ๊ฒฝ์šฐ
    if (idx == word.length()) {
        if (!node.endOfWord) throw new Error(word + " not exist"); // ๋‹จ์–ด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Œ
        node.endOfWord = false; // ๋‹จ์–ด์˜ ๋ ๋ฌธ์ž ํ‘œ์‹œ๋ฅผ false๋กœ ๋ณ€๊ฒฝ: ํ•ด๋‹น ๋ฌธ์ž ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•จ
        return; // ๋ฆฌํ”„ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ ๋…ธ๋“œ๋กœ return
    }
    char c = word.charAt(idx); // ํ˜„์žฌ ํ™•์ธํ•ด์•ผํ•˜๋Š” ๋ฌธ์ž
    if (!node.childNode.containsKey(c)) throw new Error(word + " not exist"); // ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ(=๋‹จ์–ด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ)
    Node child = node.childNode.get(c); // ์ž์‹ ๋…ธ๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ
    // ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฆฌํ”„ ๋…ธ๋“œ๊นŒ์ง€ ๋‚ด๋ ค๊ฐ€์•ผ ํ•˜๋ฏ€๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ
    delete(child, word, idx+1);
    // ํ˜„ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ์ด๊ณ (=์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†์Œ), ๋‹จ์–ด์˜ ๋์ธ ๋ฌธ์ž๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์‚ญ์ œ
    if (child.childNode.isEmpty() && !child.endOfWord) node.childNode.remove(c, child);
}

 

๐Ÿงช ๊ตฌํ˜„ ํ…Œ์ŠคํŠธ

public static void main(String[] args) {
        Trie trie = new Trie();
        // insert
        String[] arr = {"apple", "app", "dream", "dad", "age"};
        for (String word: arr) {
            trie.insert(word);
        }
        // delete
        trie.delete("app");
        trie.delete("dream");
        // contains
        System.out.println(trie.contains("apple")); // true
        System.out.println(trie.contains("app")); // ์‚ญ์ œํ–ˆ์œผ๋ฏ€๋กœ false
        System.out.println(trie.contains("age")); // true
        System.out.println(trie.contains("dream")); // ์‚ญ์ œํ–ˆ์œผ๋ฏ€๋กœ false
        System.out.println(trie.contains("dad")); // true
}

 

์œ„์—์„œ ์˜ˆ์‹œ๋กœ ๋“ค์—ˆ๋˜ ๋ฌธ์ž์—ด ๋ฐฐ์—ด์„ ๊ธฐ์ค€์œผ๋กœ ํŠธ๋ผ์ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ญ์ œ, ํฌํ•จ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ’ก ์ „์ฒด ์ฝ”๋“œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

 

Algorithm/src/Trie.java at main · hywnj/Algorithm

Contribute to hywnj/Algorithm development by creating an account on GitHub.

github.com

 

4. ํŠธ๋ผ์ด(Trie) ์‹œ๊ฐ„ ๋ณต์žก๋„

์ด ๋ฌธ์ž์˜ ๊ฐœ์ˆ˜๋ฅผ N, ๊ฐ€์žฅ ๊ธด ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๊ฐ€ L์ด๋ผ๊ณ  ํ• ๋•Œ

  • ์ƒ์„ฑ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N*L)
    • ๋ชจ๋“  ๋ฌธ์ž์—ด N๊ฐœ๋ฅผ ๋„ฃ์–ด์•ผํ•˜๊ณ , N๊ฐœ์— ๋Œ€ํ•ด ํŠธ๋ผ์ด์— ๋„ฃ๋Š” ๊ฑด ๊ฐ€์žฅ ๊ธด ๋ฌธ์ž์—ด ๊ธธ์ด์ธ L๋งŒํผ ๊ฑธ๋ฆฐ๋‹ค.
    • ์‚ฝ์ž…์€ O(L)๋งŒ ์†Œ์š”
  • ํƒ์ƒ‰ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(L)
    • ํŠธ๋ฆฌ๋ฅผ ๊ฐ€์žฅ ๊นŠ๊ฒŒ ํƒ์ƒ‰ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฐ€์žฅ ๊ธด ๋ฌธ์ž์—ด ๊ธธ์ด์ธ L๊นŒ์ง€ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ด๋ฏ€๋กœ O(L)

 

5. ํŠธ๋ผ์ด(Trie) ์žฅ๋‹จ์ 

  • ๋ฌธ์ž์—ด์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰์„ ๋น ๋ฅด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฌธ์ž์—ด์„ ์ง‘ํ•ฉ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๋งŒํผ ๋…ธ๋“œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ž์—ด์˜ ์ถ”๊ฐ€์™€ ํƒ์ƒ‰ ๋ชจ๋‘ O(M)๋งŒ์— ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ํ•„์š”๋กœ ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฌ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ฐ ๋…ธ๋“œ์—์„œ ์ž์‹๋“ค์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋“ค์„ ๋ฐฐ์—ด๋กœ ๋ชจ๋‘ ์ €์žฅํ•˜๊ณ  ์žˆ๊ธฐ์— ์ €์žฅ๊ณต๊ฐ„์˜ ํฌ๊ธฐ๊ฐ€ ํฌ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฌธ์ž์—ด์ด ๋ชจ๋‘ ์˜์†Œ๋ฌธ์ž๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์–ด๋„, ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” 26๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ์ €์ •ํ•ด์•ผํ•˜๋Š”๋ฐ
    • ์ตœ์•…์˜ ๊ฒฝ์šฐ์—๋Š” ์ง‘ํ•ฉ์— ํฌํ•จ๋˜๋Š” ๋ฌธ์ž์—ด์˜ ๊ธธ์ด์˜ ์ด ํ•ฉ๋งŒํผ์˜ ๋…ธ๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”๋ชจ๋ฆฌ๋Š” O(ํฌ์ธํ„ฐ ํฌ๊ธฐ*ํฌ์ธํ„ฐ ๋ฐฐ์—ด ๊ฐœ์ˆ˜*์ด ๋…ธ๋“œ ๊ฐœ์ˆ˜)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
      • ๋งŒ์•ฝ 1,000์ž๋ฆฌ์˜ ๋ฌธ์ž์—ด์ด 1,000๋งŒ๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด๋•Œ, 100๋งŒ๊ฐœ์˜ ๋…ธ๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ํฌ์ธํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ 8Byte๋ผ ํ•˜๋ฉด ์•ฝ 200MB์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํŠธ๋ผ์ด(Trie) ๋‹จ์  ํ•ด๊ฒฐ์„ ์œ„ํ•œ ๋ฐฉ๋ฒ•

'๋ฉ”๋ชจ๋ฆฌ์˜ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฐ' ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๋ณดํ†ต map์ด๋‚˜ vector๋ฅผ ์ด์šฉํ•ด์„œ ํ•„์š”ํ•œ ๋…ธ๋“œ๋งŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์ด ํƒ€์ดํŠธํ•œ ๊ฒฝ์šฐ์—๋Š” ์ตœ์ ํ™”๊ฐ€ ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ฌธ์ œ์—์„œ ์ฃผ์–ด์ง„ ์กฐ๊ฑด์„ ๋ณด๊ณ  ํŠธ๋ผ์ด๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ธ์ง€ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

6. ํŠธ๋ผ์ด(Trie) ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ๋ฌธ์ œ

 

์ฐธ๊ณ ํ•œ ๋งํฌ

+ Recent posts