Post

🐣 4. Trees and Graphs

4. Trees and Graphs

πŸ“š 1. 트리의 μ’…λ₯˜

  • μž¬κ·€μ  μ„€λͺ…법
  • λ…Έλ“œλ‘œ 이루어진 자료 ꡬ쑰
  • ν•˜λ‚˜μ˜ 루트 λ…Έλ“œλ₯Ό 가짐


  • μž¬κ·€ (μ•„λž˜ ꡬ쑰 반볡)
    • 루트 λ…Έλ“œ : 0개 μ΄μƒμ˜ μžμ‹ λ…Έλ“œ
    • μžμ‹ λ…Έλ“œ : 0개 μ΄μƒμ˜ μžμ‹ λ…Έλ“œ


  • 사이클 쑴재 ❌
  • 각 λ…Έλ“œλŠ” μ–΄λ–€ μžλ£Œν˜•μœΌλ‘œλ„ ν‘œν˜„ κ°€λŠ₯


1
2
3
4
class Node {
	public String name;
	public Node[] children;
}


πŸ’‘ Node 클래슀λ₯Ό ν¬ν•¨ν•˜λ„λ‘ Tree 클래슀λ₯Ό μ •μ˜ν•  수 μžˆμ§€λ§Œ.. ꡳ이..? μ‚¬μš©ν•œλ‹€κ³  ν•΄μ„œ μ½”λ“œκ°€ 더 쒋아지진 μ•ŠμŒ

1
2
3
class Tree {
	public Node root;
}



트리 πŸ†š 이진 트리

  • 이진 트리(binara tree)
    • 각 λ…Έλ“œκ°€ μ΅œλŒ€ 두 개의 μžμ‹μ„ κ°–λŠ” 트리
    • μžμ‹μ΄ μ—†λŠ” λ…Έλ“œ : 말단 λ…Έλ“œ(Nil)


이진 트리 πŸ†š 이진 탐색 트리

ch4-img1

  • ${λͺ¨λ“  μ™Όμͺ½ μžμ‹λ“€} <= n < {λͺ¨λ“  였λ₯Έμͺ½ μžμ‹λ“€}$ 의 속성은 λͺ¨λ“  λ…Έλ“œ n에 λŒ€ν•˜μ—¬ 항상 μ°Έ
  • 뢀등식은 λ‚΄ 밑에 μžˆλŠ” λͺ¨λ“  μžμ‹ λ…Έλ“œλ“€μ— λŒ€ν•΄μ„œ 참이어야함


⭐️ 이진 탐색 νŠΈλ¦¬μ—μ„œ 같은 값을 μ²˜λ¦¬ν•˜λŠ” 방식

  1. νŠΈλ¦¬λŠ” μ€‘λ³΅λœ 값을 가지면 μ•ˆλœλ‹€?
  2. μ€‘λ³΅λœ 값은 였λ₯Έμͺ½ ν˜Ήμ€ μ–‘μͺ½ μ–΄λŠ 곳이든 μ‘΄μž¬ν•  수 μžˆλ‹€?

πŸ‘‰πŸ» λͺ¨λ‘ λ§žλŠ” λ§μ΄λ―€λ‘œ μ²˜μŒμ— 트리의 μ •μ˜λ₯Ό μ–΄λ–»κ²Œ ν•˜λŠλƒμ— 따라 λ‹¬λ €μžˆλ‹€.


πŸ’‘ 트리 λ¬Έμ œκ°€ 주어지면 이진 탐색 트리일 것이라고 κ°€μ •ν•˜λŠ” κ²½μš°κ°€ 많음 (β‡’ 인터뷰 문제둜 μ œμ‹œλ˜λ©΄ 이진 탐색 νŠΈλ¦¬μΈμ§€ μ•„λ‹Œμ§€ ν™•μ‹€νžˆ 물어봐야함)


κ· ν˜• πŸ†š λΉ„κ· ν˜•

  • β€˜κ· ν˜•β€™ 트리
    • $O(logN)$ μ‹œκ°„μ— insert 와 find λ₯Ό ν•  수 μžˆμ„ μ •λ„λ‘œ κ· ν˜•μ΄ 잘 μž‘ν˜€μžˆλ‹€λ₯Ό λŒ€μΆ© 척도둀 μ‚ΌλŠ”λ‹€.
  • e.g. β€˜λ ˆλ“œ-λΈ”λž™ νŠΈλ¦¬β€™, β€˜AVL νŠΈλ¦¬β€™


μ™„μ „ 이진 트리

ch4-img2

  • 트리의 λͺ¨λ“  λ†’μ΄μ—μ„œ λ…Έλ“œκ°€ 꽉 μ°¨ μžˆλŠ” 이진 트리
  • λ§ˆμ§€λ§‰ λ‹¨κ³„μ—λŠ” 꽉 μ°¨ μžˆμ§€ μ•Šμ•„λ„ λ˜μ§€λ§Œ λ…Έλ“œκ°€ μ’Œμ—μ„œ 우둜 μ±„μ›Œμ Έμ•Όν•œλ‹€.


μ „ 이진 트리

ch4-img3

  • λͺ¨λ“  λ…Έλ“œμ˜ μžμ‹μ΄ μ—†κ±°λ‚˜ μ •ν™•νžˆ 두 개 μžˆλŠ” 경우
  • μžμ‹ ν•˜λ‚˜λ§Œ μžˆλŠ” λ…Έλ“œ ❌


포화 이진 트리

ch4-img4

  • μ „ 이진 νŠΈλ¦¬μ΄λ©΄μ„œ μ™„μ „ 이진 트리인 경우
  • λ§ˆμ§€λ§‰ λ‹¨κ³„μ—μ„œ λ…Έλ“œμ˜ κ°œμˆ˜κ°€ μ΅œλŒ€κ°€ λ˜μ–΄μ•Όν•¨
  • λ…Έλ“œμ˜ κ°œμˆ˜κ°€ μ •ν™•νžˆ $2^{k-1}$ 개 ($k$ : 높이)


이진 트리 순회

πŸ’‘ 루트 λ…Έλ“œμ˜ 순회 μˆœμ„œμ— 따라 λͺ…λͺ…


  • μ€‘μœ„ 순회
1
2
3
4
5
6
7
void inOrderTraversal(TreeNode node) {
  if (node != null) {
    inOrderTraversal(node.left);
    visite(node);
    inOrderTraversal(node.right);
  }
}


  • μ „μœ„ 순회
1
2
3
4
5
6
7
void preTraverse(TreeNode node) {
  if (node != null) {
    visit(node);
    preTraverse(node.left);
    preTraverse(node.right);
  }
}


  • ν›„μœ„ 순회
1
2
3
4
5
6
7
void postTraverse(TreeNode node) {
  if (node != null) {
    postTraverse(node.left);
    postTraverse(node.right);
    visit(node);
  }
}



이진 νž™(μ΅œμ†Œ/μ΅œλŒ€ νž™)

  • μ΅œμ†Œνž™(min-heaps)
    • μ›μ†Œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬
  • μ΅œλŒ€νž™(max-heaps)
    • μ›μ†Œ λ‚΄λ¦Όμ°¨μˆœ μ •λ ¬


  • μ΅œμ†Œνž™ πŸ’‘ μ΅œλŒ€νž™μ€ μ΅œμ†Œνž™κ³Ό 방식이 μ™„μ „νžˆ 동일(μ •λ ¬ μˆœμ„œλ§Œ 닀름)
  • μ™„μ „ 이진 트리
  • 각 λ…Έλ“œμ˜ μ›μ†Œκ°€ μžμ‹λ“€μ˜ μ›μ†Œλ³΄λ‹€ μž‘λ‹€
  • 루트 : 트리 μ „μ²΄μ—μ„œ κ°€μž₯ μž‘μ€ μ›μ†Œ


  • μ—°μ‚°
    • insert
    • extract_min


  • μ‚½μž… ch4-img5
  • $O(log n)$ μ†Œμš”


  • 트리의 λ°‘λ°”λ‹₯μ—μ„œλΆ€ν„° μ‚½μž…
  • μƒˆλ‘œμš΄ μ›μ†Œ : λ°‘λ°”λ‹₯ κ°€μž₯ 였λ₯Έμͺ½ μœ„μΉ˜λ‘œ μ‚½μž…
  • μƒˆλ‘œ μ‚½μž…λœ μ›μ†Œκ°€ μ œλŒ€λ‘œ 된 자리 찾을 λ•ŒκΉŒμ§€ λΆ€λͺ¨ λ…Έλ“œμ™€ κ΅ν™˜ -> μ΅œμ†Œ μ›μ†Œλ₯Ό μœ„μͺ½μœΌλ‘œ 올림


  • μ΅œμ†Œ μ›μ†Œ 뽑아내기 ch4-img6
  • $O(log n)$ μ†Œμš”


  • μ΅œμ†Œ μ›μ†Œλ₯Ό μ œκ±°ν•œ 후에 νž™μ— μžˆλŠ” κ°€μž₯ λ§ˆμ§€λ§‰ μ›μ†Œ(λ°‘λ°”λ‹₯ κ°€μž₯ μ™Όμͺ½ μ›μ†Œ)와 κ΅ν™˜
  • 쒌/우 μžμ‹ 쀑 더 μž‘μ€ μ›μ†Œμ™€ κ΅ν™˜


트라이

ch4-img7

  • 접두사 트리(prefix tree)

  • nμ°¨ 트리의 λ³€μ’…
  • 각 λ…Έλ“œμ— 문자λ₯Ό μ €μž₯ν•˜λŠ” 자료ꡬ쑰
    • 트리λ₯Ό μ•„λž˜μͺ½μœΌλ‘œ μˆœνšŒν•˜λ©΄ 단어 ν•˜λ‚˜κ°€ λ‚˜μ˜¨λ‹€.


  • e.g. μœ νš¨ν•œ 단어 집합을 μ΄μš©ν•˜λŠ” 문제
    • 접두사λ₯Ό λΉ λ₯΄κ²Œ 찾아보기 μœ„ν•¨ - 주어진 λ¬Έμžμ—΄μ΄ μœ ν˜€ν•œμ§€ μ•„λ‹Œμ§€ λΉ λ₯΄κ²Œ 확인
    • 길이가 $k$인 λ¬Έμžμ—΄μ΄ μ£Όμ–΄μ‘Œμ„ λ•Œ $O(k)$ μ‹œκ°„μ— ν•΄λ‹Ή λ¬Έμžμ—΄μ΄ μœ νš¨ν•œ 접두사인지 확인 κ°€λŠ₯
    • 트리의 ν˜„μž¬ λ…Έλ“œλ₯Ό μ°Έμ‘°κ°’μœΌλ‘œ λ„˜κ²¨μ„œ 접두어 반볡 탐색 κ°€λŠ₯


  • λ‹¨μ–΄μ˜ 끝
    • Null node (* Node) 둜 ν‘œν˜„
      • 각 λ…Έλ“œλŠ” 1 ~ {단어 길이 + 1} 개의 μžμ‹ λ…Έλ“œλ₯Ό κ°€μ§ˆ 수 있음
    • λΆ€λͺ¨ λ…Έλ“œ μ•ˆμ— boolean flagλ₯Ό μƒˆλ‘œ μ •μ˜ν•΄μ„œ λ‹¨μ–΄μ˜ 끝을 ν‘œν˜„ν•˜κΈ°λ„ 함
      • 각 λ…Έλ“œλŠ” 0 ~ {단어 길이} 개의 μžμ‹ λ…Έλ“œλ₯Ό κ°€μ§ˆ 수 있음


κ·Έλž˜ν”„

  • $Tree βŠ‚ Graph$
  • 트리 : 사이클이 μ—†λŠ” ν•˜λ‚˜μ˜ μ—°κ²° κ·Έλž˜ν”„
  • κ·Έλž˜ν”„ : λ‹¨μˆœνžˆ λ…Έλ“œμ™€ κ·Έ λ…Έλ“œλ₯Ό μ—°κ²°ν•˜λŠ” 간선을 ν•˜λ‚˜λ‘œ λͺ¨μ•„ 놓은 것


  • κ·Έλž˜ν”„μ—λŠ” λ°©ν–₯성이 μžˆμ„ μˆ˜λ„ 있고 없을 μˆ˜λ„ μžˆλ‹€.
  • κ·Έλž˜ν”„ : λΆ€λΆ„ κ·Έλž˜ν”„λ‘œ ꡬ성 κ°€λŠ₯
    • μ—°κ²° κ·Έλž˜ν”„ : λͺ¨λ“  정점 쌍 간에 κ²½λ‘œκ°€ μ‘΄μž¬ν•˜λŠ” κ·Έλž˜ν”„
    • λΉ„μˆœν™˜ κ·Έλž˜ν”„ : 사이클이 μ—†λŠ” κ·Έλž˜ν”„


κ·Έλž˜ν”„ ν‘œν˜„ 방식

  1. 인접 리슀트
  • λ…Έλ“  정점을 인접 λ¦¬μŠ€νŠΈμ— μ €μž₯
  • νŠΈλ¦¬μ—μ„œλŠ” νŠΉμ • λ…Έλ“œ(root) λ‹€λ₯Έ λͺ¨λ“  λ…Έλ“œλ‘œ μ ‘κ·Ό κ°€λŠ₯ But, κ·Έλž˜ν”„λŠ” νŠΉμ • λ…Έλ“œμ—μ„œ λ‹€λ₯Έ λͺ¨λ“  λ…Έλ“œλ‘œ μ ‘κ·Ό λΆˆκ°€


1
2
3
4
5
6
7
8
class Graph {
  public Node[] nodes;
}

class Node {
  public String name;
  public Node[] children;
}


  1. 인접 ν–‰λ ¬

ch4-img8

  • N X N boolean matrix
  • matrix[i][j] == true : iμ—μ„œ j둜의 κ°„μ„  쑴재
  • 무방ν–₯ κ·Έλž˜ν”„μ˜ 인접 ν–‰λ ¬ ν˜•νƒœ : λŒ€μΉ­ ν–‰λ ¬(λŒ€κ°μ„ μ„ κΈ°μ€€μœΌλ‘œ)


κ·Έλž˜ν”„ 탐색

ch4-img9

  1. 깊이 μš°μ„  탐색(DFS)
  • 루트 λ…Έλ“œμ—μ„œ μ‹œμž‘ν•΄μ„œ λ‹€μŒ λΆ„κΈ°λ‘œ λ„˜μ–΄κ°€κΈ° 전에 ν•΄λ‹Ή λΆ„κΈ°λ₯Ό μ™„λ²½ν•˜κ²Œ νƒμƒ‰ν•˜λŠ” 방법
  • λ„“κ²Œ νƒμƒ‰ν•˜κΈ° 전에 깊게 탐색
  • 트리 μˆœνšŒλŠ” λͺ¨λ‘ DFS의 ν•œ μ’…λ₯˜
  • μž¬κ·€μ  λ™μž‘
  • e.g. λͺ¨λ“  λ…Έλ“œ λ°©λ¬Έ


1
2
3
4
5
6
7
8
9
void search(Node root){
  if (root == null) return;
  visit(root);
  for each(Node n in root.adjacent) {
    if (n.visited == false) {
      search(n);
    }
  }
}


  1. λ„ˆλΉ„ μš°μ„  탐색(BFS)
  • 루트 λ…Έλ“œμ—μ„œ μ‹œμž‘ν•΄μ„œ μΈμ ‘ν•œ λ…Έλ“œ λ¨Όμ € 탐색
  • 깊게 νƒμƒ‰ν•˜κΈ° 전에 λ„“κ²Œ 탐색
  • 큐λ₯Ό μ΄μš©ν•œ 반볡적 ν˜•νƒœ
  • e.g. 두 λ…Έλ“œ 사이 μ΅œλ‹¨/μž„μ˜ 경둜 탐색


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);
      }
    }
  }
}



μ–‘λ°©ν–₯ 탐색

ch4-img10

  • μΆœλ°œμ§€μ™€ 도착지 두 λ…Έλ“œμ—μ„œ λ™μ‹œμ— λ„ˆλΉ„ μš°μ„  탐색 μˆ˜ν–‰ ν›„, 두 탐색 지점이 μΆ©λŒν•˜λŠ” 경우 경둜 탐색
  • 전톡적인 λ„ˆλΉ„ μš°μ„  탐색 : $O(k^d)$
  • μ–‘λ°©ν–₯ 탐색 : $O(k^{d/2})$
This post is licensed under CC BY 4.0 by the author.