πΉ 4. Trees and Graphs
[ νΈλ¦¬μ μ’ λ₯ ]
νΈλ¦¬λ λ Έλλ‘ μ΄λ£¨μ΄μ§ μλ£κ΅¬μ‘°μ΄λ€.
- νΈλ¦¬λ νλμ λ£¨νΈ λ Έλλ₯Ό κ°λλ€
- λ£¨νΈ λ Έλλ 0κ° μ΄μμ μμ λ Έλλ₯Ό κ°κ³ μλ€.
- κ·Έ μμ λ Έλ λν 0κ° μ΄μμ μμ λ Έλλ₯Ό κ°κ³ μκ³ , μ΄λ λ°λ³΅μ μΌλ‘ μ μλλ€.
νΈλ¦¬μλ μ¬μ΄ν΄(cycle)μ΄ μ‘΄μ¬ν μ μλ€. λ Έλλ€μ νΉμ μμλ‘ λμ΄λ μλ μκ³ κ·Έλ΄ μ μμ μλ μλ€. κ° λ Έλλ μ΄λ€ μλ£νμΌλ‘λ νν κ°λ₯νλ€.
Node ν΄λμ€λ₯Ό κ°λ¨νκ² μ μνλ©΄ λ€μκ³Ό κ°λ€.
1
2
3
4
class Node {
public String name;
public Node[] children;
}
λ Έλ ν΄λμ€λ₯Ό ν¬ν¨νλ Tree ν΄λμ€λ₯Ό μ μν μλ μμ§λ§, κ΅³μ΄ νμ§ μκ² λ€.
νΈλ¦¬ vs μ΄μ§νΈλ¦¬
μ΄μ§νΈλ¦¬(binary tree) : κ° λ Έλκ° μ΅λ λ κ°μ μμμ κ°λ νΈλ¦¬
λͺ¨λ νΈλ¦¬κ° μ΄μ§νΈλ¦¬λ μλλ€.
μμμ΄ μλ λ Έλλ βλ§λ¨β λ ΈλλΌκ³ λΆλ₯Έλ€.
μ΄μ§ νΈλ¦¬ vs μ΄μ§ νμ νΈλ¦¬
μ΄μ§ νμ νΈλ¦¬ : λͺ¨λ λ Έλκ° βλͺ¨λ μΌμͺ½ μμλ€ β€ n < λͺ¨λ μ€λ₯Έμͺ½ μμλ€β μμ±μ κ°μ§λ μ΄μ§νΈλ¦¬
νΈλ¦¬ λ¬Έμ κ° μ£Όμ΄μ‘μ λ λ³΄ν΅ μ΄μ§ νμ νΈλ¦¬μΌ κ²μ΄λΌ κ°μ ν΄ λ²λ¦¬λλ°, μ΄μ§ νμ νΈλ¦¬μΈμ§ μλμ§ νμ€ν νλλ‘ ν΄μΌνλ€.
κ· ν vs λΉκ· ν
κ· νμ μ‘λλ€λ κ²μ΄ μΌμͺ½κ³Ό μ€λ₯Έμͺ½ λΆλΆ νΈλ¦¬μ ν¬κΈ°κ° μμ ν κ°κ² νλ κ²μ μλ―Ένμ§ μλλ€. βκ· νβ νΈλ¦¬μΈμ§ μλμ§ νμΈνλ λ°©λ² μ€ νλλ βλ무 λΆκ· νν건 μλμ§β νμΈνλ κ² μ΄μμ μλ―Έλ₯Ό κ°λλ€. O(logN) μκ°μ insertμ findλ₯Ό ν μ μμ μ λλ‘ κ· νμ΄ μ μ‘ν μμ§λ§, κ·Έλ λ€κ³ κΌ μλ²½νκ² κ· ν μ‘ν μμ νμλ μλ€.
- κ· ν νΈλ¦¬μ μΌλ°μ μ ν
- λ λ-λΈλ νΈλ¦¬
- AVL νΈλ¦¬
μμ μ΄μ§ νΈλ¦¬(complete binary tree)
: νΈλ¦¬μ λͺ¨λ λμ΄μμ λ Έλκ° κ½ μ°¨ μλ μ΄μ§ νΈλ¦¬
λ§μ§λ§ λ¨κ³(level)λ κ½ μ°¨ μμ§ μμλ λμ§λ§ λ Έλκ° μΌμͺ½μμ μ€λ₯Έμͺ½μΌλ‘ μ±μμ ΈμΌ νλ€.
μ μ΄μ§ νΈλ¦¬(full binary tree)
: λͺ¨λ λ Έλμ μμμ΄ μκ±°λ μ νν λ κ° μλ κ²½μ°
μμμ΄ νλλ§ μλ λ Έλκ° μ‘΄μ¬ν΄μλ μ λλ€.
ν¬ν μ΄μ§ νΈλ¦¬(perfect binary tree)
: μ μ΄μ§ νΈλ¦¬μ΄λ©΄μ μμ μ΄μ§ νΈλ¦¬μΈ κ²½μ°
λͺ¨λ λ§λ¨ λ Έλλ κ°μ λμ΄μ μμ΄μΌ νλ©°, λ§μ§λ§ λ¨κ³μμ λ Έλμ κ°μκ° μ΅λκ° λμ΄μΌ νλ€.
ν¬ν μ΄μ§ νΈλ¦¬λ λ Έλμ κ°μκ° μ νν \(2^{k-1}\) (\(k\)λ νΈλ¦¬μ λμ΄)κ°μ¬μΌ νλ€.
[ μ΄μ§ νΈλ¦¬ μν ]
μ€μ(in-order), νμ(post-order), μ μ(pre-order)
μ΄ μ€ κ°μ₯ λΉλ²νκ² μ¬μ©λλ μν λ°©μμ μ€μ μνμ΄λ€.
μ€μ μν(in-order traversal)
: μΌμͺ½ κ°μ§(branch), νμ¬ λ Έλ, μ€λ₯Έμͺ½ κ°μ§ μμλ‘ λ Έλλ₯Ό βλ°©λ¬Έβνκ³ μΆλ ₯νλ λ°©λ²
1
2
3
4
5
6
7
void inOrderTraversal(TreeNode node) {
if (node != null) {
inOrderTraversal(node.left);
visit(node);
inOrderTraversal(node.right);
}
}
μ΄μ§ νμ νΈλ¦¬λ₯Ό μ΄ λ°©μμΌλ‘ μννλ€λ©΄ μ€λ¦μ°¨μμΌλ‘ λ°©λ¬Ένκ² λλ€.
μ μ μν(pre-order traversal)
: μμ λ Έλλ³΄λ€ νμ¬ λ Έλλ₯Ό λ¨Όμ λ°©λ¬Ένλ λ°©λ²
1
2
3
4
5
6
7
void preOrderTraversal(TreeNode node) {
if (node != null) {
visit(node);
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
}
μ μ μνμμ κ°μ₯ λ¨Όμ λ°©λ¬Ένκ² λ λ Έλλ μΈμ λ 루νΈμ΄λ€.
νμ μν(post-order traversal)
: λͺ¨λ μμ λ Έλλ€μ λ¨Όμ λ°©λ¬Έν λ€ λ§μ§λ§μ νμ¬ λ Έλλ₯Ό λ°©λ¬Ένλ λ°©λ²
1
2
3
4
5
6
7
void postOrderTraversal(TreeNode node) {
if (node != null) {
postOrderTraversal(node.left);
postOrderTraversal(node.right);
visit(node);
}
}
νμ μνμμ κ°μ₯ λ§μ§λ§μ λ°©λ¬Ένκ² λ λ Έλλ μΈμ λ 루νΈμ΄λ€.
[ μ΄μ§ ν(μ΅μνκ³Ό μ΅λν) ]
μ΅μν(min-heaps)λ§ λ€λ£° κ²μ΄λ€. μ΅λν(max-heaps)μ μμκ° λ΄λ¦Όμ°¨μμΌλ‘ μ λ ¬λμ΄ μλ€λ μ λ§ λ€λ₯Ό λΏ, μ΅μνκ³Ό μμ ν κ°λ€.
μ΅μνμ νΈλ¦¬μ λ§μ§λ§ λ¨κ³μμ μ€λ₯Έμͺ½ λΆλΆμ λΊ λλ¨Έμ§ λΆλΆμ΄ κ°λ μ±μμ Έ μλ€λ μ μμ μμ μ΄μ§ νΈλ¦¬μ΄λ©°, κ° λ Έλμ μμκ° μμλ€μ μμλ³΄λ€ μλ€λ νΉμ±μ΄ μλ€. λ°λΌμ 루νΈλ νΈλ¦¬ μ 체μμ κ°μ₯ μμ μμκ° λλ€.
μ΅μνμλ insertμ extract_minμ΄λΌλ ν΅μ¬ μ°μ° λ κ°μ§κ° μ‘΄μ¬νλ€.
μ½μ
μ΅μνμ μμλ₯Ό μ½μ ν λλ μΈμ λ νΈλ¦¬μ λ°λ°λ₯μμλΆν° μ½μ μ μμνλ€. μμ νΈλ¦¬μ μμ±μ μλ°°λμ§ μκ² μλ‘μ΄ μμλ λ°λ°λ₯ κ°μ₯ μ€λ₯Έμͺ½ μμΉλ‘ μ½μ λλ€.
μλ‘ μ½μ λ μμκ° μ λλ‘ λ μ리λ₯Ό μ°Ύμ λκΉμ§ λΆλͺ¨ λ Έλμ κ΅νν΄λκ°λ€. κΈ°λ³Έμ μΌλ‘ μ΄μ κ°μ λ°©μμΌλ‘ μ΅μ μμλ₯Ό μμͺ½μΌλ‘ μ¬λ¦°λ€.
νμ μλ λ Έλμ κ°μλ₯Ό nμ΄λΌ ν λ μμ μ°μ°μ O(log n) μκ°μ΄ κ±Έλ¦°λ€.
μ΅μ μμ λ½μλ΄κΈ°
μ΅μνμμ μ΅μ μμλ μΈμ κ° κ°μ₯ μμ λμΈλ€.
- μ΅μ μμλ₯Ό μ κ±°ν νμ νμ μλ κ°μ₯ λ§μ§λ§ μμ(λ°λ°λ₯ κ°μ₯ μΌμͺ½)μ κ΅ννλ€.
- μ΅μνμ μ±μ§μ λ§μ‘±νλλ‘, ν΄λΉ λ Έλλ₯Ό μμ λ Έλμ κ΅νν΄ λκ°μΌλ‘μ¨ λ°μΌλ‘ λ΄λ³΄λΈλ€.(μΌμͺ½ μμ, μ€λ₯Έμͺ½ μμ μ€ λ μμ μμμ κ΅ν)
O(log n) μκ°μ΄ κ±Έλ¦°λ€.
[ νΈλΌμ΄(μ λμ¬ νΈλ¦¬) ]
: nμ°¨ νΈλ¦¬(n-ary tree)μ λ³μ’ μΌλ‘ κ° λ Έλμ λ¬Έμλ₯Ό μ μ₯νλ μλ£κ΅¬μ‘°
νΈλ¦¬λ₯Ό μλμͺ½μΌλ‘ μννλ©΄ λ¨μ΄ νλκ° λμ¨λ€.
λ λ Έλ(null node)λΌκ³ λ λΆλ¦¬μ°λ β* λ Έλβλ μ’ μ’ λ¨μ΄μ λμ λνλΈλ€.
ex) MANY μ΄ν β* λ Έλβκ° λμ€λ©΄ MANYλΌλ λ¨μ΄κ° μμ±λμμμ μλ¦°λ€.
MAλΌλ κ²½λ‘κ° μ‘΄μ¬νλ€λ μ¬μ€μ MAλ‘ μμνλ λ¨μ΄κ° μλ€λ κ²μ΄λ€.
νΈλΌμ΄μμ κ° λ Έλλ 1κ°μμ ALPHABET_SIZE + 1κ°κΉμ§ μμμ κ°κ³ μμ μ μλ€. (λ§μ½ β* λ Έλβ λμ boolean νλκ·Έλ‘ νννλ€λ©΄ 0κ°μμ ALPHABET_SIZEκΉμ§)
μ λμ¬λ₯Ό λΉ λ₯΄κ² μ°Ύμ보기 μν μμ£Ό νν λ°©μμΌλ‘, λͺ¨λ μΈμ΄λ₯Ό νΈλΌμ΄μ μ μ₯ν΄λλ λ°©μμ΄ μλ€.
ν΄μν μ΄λΈμ μ΄μ©νλ©΄ μ£Όμ΄μ§ λ¬Έμμ΄μ΄ μ ν¨νμ§ μλμ§ λΉ λ₯΄κ² νμΈν μ μμ§λ§, κ·Έ λ¬Έμμ΄μ΄ μ΄λ€ μ ν¨ν λ¨μ΄μ μ λμ¬μΈμ§ νμΈν μλ μλ€. νΈλΌμ΄λ₯Ό μ΄μ©νλ©΄ μμ£Ό λΉ λ₯΄κ² νμΈν μ μλ€.
β νΈλΌμ΄λ κΈΈμ΄κ° KμΈ λ¬Έμμ΄μ΄ μ£Όμ΄μ‘μ λ O(K) μκ°μ ν΄λΉ λ¬Έμμ΄μ΄ μ ν¨ν μ λμ¬μΈμ§ νμΈν μ μλ€. μ΄ μκ°μ ν΄μν μ΄λΈμ μ¬μ©νμ λμ μ νν κ°μ μν μκ°μ΄λ€. κ²μ O(1) μ λ ₯ λ¬Έμμ΄ μ½κΈ° O(K)
μ ν¨ν λ¨μ΄ μ§ν©μ μ΄μ©νλ λ§μ λ¬Έμ λ€μ νΈλΌμ΄λ₯Ό ν΅ν΄ μ΅μ νν μ μλ€.
νΈλ¦¬μμ μ°κ΄λ μ λμ¬λ₯Ό λ°λ³΅μ μΌλ‘ κ²μν΄μΌ νλ μν©μμ(ex. M, MA, MAN, MANYλ₯Ό μ°¨λ‘λλ‘ μ΄ν΄λ³΄λ μν©), νΈλ¦¬μ νμ¬ λ Έλλ₯Ό μ°Έμ‘°κ°μΌλ‘ λκΈΈ μλ μλ€. β κ²μν λλ§λ€ 루νΈμμ μμν νμκ° μκ³ , λ¨μν Yκ° MANμ μμμΈμ§λ§ νμΈν΄λ³΄λ©΄ λλ€.
[ κ·Έλν ]
νΈλ¦¬(tree)λ κ·Έλν(graph)μ ν μ’ λ₯μ΄λ€. νΈλ¦¬λ μ¬μ΄ν¬μ΄ μλ νλμ μ°κ²° κ·Έλνμ΄λ€.
κ·Έλν: λ¨μν λ Έλμ κ·Έ λ Έλλ₯Ό μ°κ²°νλ κ°μ (edge)μ νλλ‘ λͺ¨μ λμ κ²
- κ·Έλνμλ λ°©ν₯μ±μ΄ μμ μλ μκ³ μμ μλ μλ€.
- λ°©ν₯μ±O : μΌλ°©ν΅ν
- λ°©ν₯μ±X : μλ°©ν₯ ν΅ν
- κ·Έλνλ μ¬λ¬ κ°μ κ³ λ¦½λ λΆλΆ κ·Έλνλ‘ κ΅¬μ±λ μ μλ€.
- κ·Έλνμλ μ¬μ΄ν΄μ΄ μ‘΄μ¬ν μλ μκ³ μ‘΄μ¬νμ§ μμ μλ μλ€.
- μ¬μ΄ν΄ μλ κ·Έλνλ βλΉμν κ·Έλνβ(acycle graph)λΌκ³ λΆλ₯Έλ€.
μΈμ 리μ€νΈ(adjacency list)
κ·Έλνλ₯Ό ννν λ μ¬μ©λλ κ°μ₯ μΌλ°μ μΈ λ°©λ²μΌλ‘ λͺ¨λ μ μ (νΉμ λ Έλ)λ₯Ό μΈμ 리μ€νΈμ μ μ₯νλ€. 무방ν₯ κ·Έλνμμ (a, b) κ°μ μ λ λ² μ μ₯λλ€.
κ·Έλνμμ λ Έλλ₯Ό μ μνλ κ°λ¨ν ν΄λμ€λ νΈλ¦¬μ λ Έλ ν΄λμ€μ κΆκ·Ήμ μΌλ‘ κ°μ 보μΈλ€.
1
2
3
4
5
6
7
class Graph {
public Node[] nodes;
}
class Node {
public String name;
public Node[] children;
}
νΈλ¦¬μμ νΉμ λ Έλ νλμμ λ€λ₯Έ λ Έλλ‘ λͺ¨λ μ κ·Ό κ°λ₯νκΈ° λλ¬Έμ Tree ν΄λμ€λ₯Ό λ°λ‘ λμ§ μμλ€. νμ§λ§ κ·Έλνλ νΈλ¦¬μ λ¬λ¦¬ νΉμ λ Έλμμ λ€λ₯Έ λͺ¨λ λ Έλλ‘ μ κ·Όμ΄ κ°λ₯νμ§λ μμ Graph λΌλ ν΄λμ€λ₯Ό μ¬μ©νλ€.
μΈμ νλ ¬
$N\times N$ λΆλ¦° νλ ¬(boolean matrix)λ‘μ¨ matrix[i][j]κ° trueλΌλ©΄ iμμ jλ‘μ κ°μ μ΄ μλ€λ λ»μ΄λ€. μ¬κΈ°μ Nμ λ Έλμ κ°μλ₯Ό λ»νλ€.
κ·Έλν νμ
μΌλ°μ μΈ λ°©λ²μΌλ‘λ κΉμ΄ μ°μ νμ(depth-first search), λλΉ μ°μ νμ(breadth-first search)μ΄ μλ€.
- κΉμ΄ μ°μ νμ(DFS)
- λ£¨νΈ λ Έλμμ μμνμ¬ ν΄λΉ λΆκΈ°λ₯Ό μλ²½νκ² νμνλ λ°©λ²
- κ·Έλνμμ λͺ¨λ λ Έλλ₯Ό λ°©λ¬Ένκ³ μ ν λ λ μ νΈλ¨
- λλΉ μ°μ νμ(BFS)
- λ£¨νΈ λ Έλμμ μμν΄μ μΈμ ν λ Έλλ₯Ό λ¨Όμ νμνλ λ°©λ²
- μ΅λ¨ κ²½λ‘ νΉμ μμμ κ²½λ‘λ₯Ό μ°Ύκ³ μΆμ λ μ νΈλ¨
κΉμ΄ μ°μ νμ(DFS)
a λ Έλλ₯Ό λ°©λ¬Έν λ€ aμ μΈμ ν λ Έλλ€μ μ°¨λ‘λ‘ μννλ€.
μ μ μνλ₯Ό ν¬ν¨ν λ€λ₯Έ ννμ νΈλ¦¬ μνλ λͺ¨λ DFSμ ν μ’ λ₯μ΄λ€.
μ΄ μκ³ λ¦¬μ¦μ ꡬνν λ κ°μ₯ ν° μ°¨μ΄μ μ, κ·Έλν νμμ κ²½μ° μ΄λ€ λ Έλλ₯Ό λ°©λ¬Ένμλμ§ μ¬λΆλ₯Ό λ°λμ κ²μ¬ν΄μΌ νλ€λ κ²μ΄λ€. μ΄λ₯Ό κ²μ¬νμ§ μμ κ²½μ° λ¬΄ν루νμ λΉ μ§ μνμ΄ μλ€.
1
2
3
4
5
6
7
8
9
10
void search(Node root) {
if (root == null) return;
visit(root);
root.visited = true;
for each (Node n in root.adjacent) {
if (n.visited == false) {
search(n);
}
}
}
λλΉ μ°μ νμ(BFS)
BFSλ μ¬κ·μ μΌλ‘ λμνμ§ μλλ€. ν(queue)λ₯Ό μ¬μ©νλ€.
a λ Έλμμ μμνλ€κ³ νμ λ, BFSλ a λ Έλμ μ΄μ λ Έλλ₯Ό λͺ¨λ λ°©λ¬Έν λ€μμ μ΄μμ μ΄μλ€μ λ°©λ¬Ένλ€. μ¦, 거리μ λ°λΌ λ¨κ³λ³λ‘ νμνλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void search(Node root) {
Queue queue = new Queue();
root.marked = true;
queue.enqueue(root); // νμ λμ μΆκ°νλ€.
while (!queue.isEmpty()) {
Node r = queue.dequeue(); // νμ μμμ λ½μλΈλ€.
visit(r);
foreach (Node n in r.adjacent) {
if (n.marked == false) {
n.marked = true;
queue.enqueue(n);
}
}
}
}
μλ°©ν₯ νμ
μλ°©ν₯ νμ(bidirectional search)μ μΆλ°μ§μ λμ°©μ§ μ¬μ΄μ μ΅λ¨ κ²½λ‘λ₯Ό μ°Ύμ λ μ¬μ©λκ³€ νλ€. κΈ°λ³Έμ μΌλ‘ μΆλ°μ§μ λμ°©μ§ λ λ Έλμμ λμμ λλΉ μ°μ νμμ μνν λ€, λ νμ μ§μ μ΄ μΆ©λνλ κ²½μ°μ κ²½λ‘λ₯Ό μ°Ύλ λ°©μμ΄λ€.
μλ°©ν₯ νμ λ°©μμ΄ μ λ λΉ λ₯Έμ§ μ΄ν΄λ³Έλ€. λͺ¨λ λ Έλκ° μ μ΄λ kκ°μ μ΄μ λ Έλμ μ°κ²°λμ΄ μκ³ sμμ tλ‘μ μ΅λ¨ κ±°λ¦¬κ° dκ° λλ κ·Έλνλ₯Ό μκ°ν΄ 보μ.
μ ν΅μ μΈ BFSλ₯Ό μ¬μ©νλ€λ©΄ 첫 λ¨κ³μμ kκ°μ λ Έλλ₯Ό νμν΄μΌ νλ€. λ€μ λ¨κ³μμ kκ°μ λ Έλλ€ λν μ΄μν kκ°μ λ Έλλ₯Ό νμν΄μΌ νλ―λ‘ μ΄ $k^2$κ°μ λ Έλλ₯Ό νμν΄μΌ νλ€.
β λ°λΌμ μ΄λ₯Ό dλ² λ°λ³΅νλ©΄ μ΄ $O(k^d)$κ°μ λ Έλλ₯Ό νμν΄μΌ νλ€.
μλ°©ν₯ νμμ μ¬μ©νλ€λ©΄ λ νμ μκ³ λ¦¬μ¦μ΄ λλ΅ d/2 λ¨κ³(sμ t μ¬μ΄μ μ€κ°μ§μ )κΉμ§ νμν νμ μΆ©λν κ²μ΄λ€. λ°λΌμ sμ t κ°κ°μμ λ°©λ¬Ένκ² λ λ Έλμ μλ λλ΅ $k^{d/2}$κ°κ° λ κ²μ΄κ³ ,
β λ°λΌμ λ°©λ¬Ένκ² λ μ 체 λ Έλλ λλ΅ $2k^{d/2}$, $O(k^{d/2})$κ°κ° λλ€.