algorithms-BFS&DFS-01.md

🏑

BFS κ΅¬ν˜„ν•˜κΈ° (feat. BSTλž€?)

Binary Search Tree, BST:
       A
     /   \
    B     C
   / \   / \
  D   E F   G

BFS: A - B - C - D - E - F - G

DFS: A - B - D - E - C - F - G
  • breadthFirstSearch()
breadthFirstSearch() {
	let currentNode = this.root; // 루트 λ…Έλ“œ
	let list = [];
	let queue = []; // λ ˆλ²¨μ„ νŠΈλž˜ν‚Ή
	queue.push(currentNode); // 큐에 루트 λ…Έλ“œλ₯Ό push

	while(queue.length > 0) { // 큐 λ°°μ—΄ 길이가 0 이상일 λ–„
		currentNode = queue.shift(); // 큐의 첫번째 μ•„μ΄ν…œ
		list.push(currentNode.value); // A둜 μ‹œμž‘

		if (currentNode.left) { // μ™Όμͺ½ μžμ‹μ„ 선택
			queue.push(currentNode.left);
		}
		if (currentNode.right) { // 였λ₯Έμͺ½ μžμ‹μ„ 선택
			queue.push(currentNode.right);
		}
		return list;
	}
}
  • breathFirstSearchRecursive()
breadthFirstSearchRecursive(queue, list) { // queue와 listλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ λ„˜κΉ€, μ•„λ‹ˆλΌλ©΄ recursive μ‹œ μ΄ˆκΈ°ν™”
	if (!queue.length) { // 큐 λ°°μ—΄ 길이가 0이라면 얼리 리턴, μž¬κ·€ μ’…λ£Œ
		return list;
	}
	let currentNode = queue.shift();
	list.push(currentNode.value); // A둜 μ‹œμž‘

	if (currentNode.left) { // μ™Όμͺ½ μžμ‹μ„ 선택
		queue.push(currentNode.left);
	}
	if (currentNode.right) { // 였λ₯Έμͺ½ μžμ‹μ„ 선택
		queue.push(currentNode.right);
	}

	return this.breadthFirstSearchRecursive(queue, list); // μž¬κ·€
}

breadthFirstSearch(tree.root, [])

BST, Binary Search Tree, 이진 트리

  • λ°”μ΄λ„ˆλ¦¬ μ„œμΉ˜ 트리(Binary Search Tree, BST)λŠ” 이진 트리(Binary Tree)의 ν•œ μ’…λ₯˜λ‘œ, λ‹€μŒκ³Ό 같은 속성을 κ°–μŠ΅λ‹ˆλ‹€:
각 λ…Έλ“œλŠ” ν•˜λ‚˜μ˜ κ°’κ³Ό μ™Όμͺ½ μ„œλΈŒνŠΈλ¦¬μ™€ 였λ₯Έμͺ½ μ„œλΈŒνŠΈλ¦¬λ₯Ό κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.
μ™Όμͺ½ μ„œλΈŒνŠΈλ¦¬μ˜ λͺ¨λ“  λ…Έλ“œμ˜ 값은 ν•΄λ‹Ή λ…Έλ“œμ˜ 값보닀 μž‘μŠ΅λ‹ˆλ‹€.
였λ₯Έμͺ½ μ„œλΈŒνŠΈλ¦¬μ˜ λͺ¨λ“  λ…Έλ“œμ˜ 값은 ν•΄λ‹Ή λ…Έλ“œμ˜ 값보닀 ν½λ‹ˆλ‹€.
μ€‘λ³΅λœ 값을 κ°€μ§€λŠ” λ…Έλ“œλŠ” μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
μ΄λŸ¬ν•œ μ†μ„±μœΌλ‘œ 인해 λ°”μ΄λ„ˆλ¦¬ μ„œμΉ˜ νŠΈλ¦¬λŠ” 데이터λ₯Ό 효율적으둜 탐색, μ‚½μž…, μ‚­μ œν•  수 μžˆλŠ” μžλ£Œκ΅¬μ‘°μž…λ‹ˆλ‹€. λ°”μ΄λ„ˆλ¦¬ μ„œμΉ˜ 트리의 μ£Όμš” νŠΉμ§•μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:
  • 탐색: 트리의 λ£¨νŠΈλΆ€ν„° μ‹œμž‘ν•˜μ—¬ 값을 μ°Ύκ±°λ‚˜, ν•΄λ‹Ή 값을 가진 λ…Έλ“œκ°€ 없을 경우 이진 탐색을 톡해 값을 μ°ΎμŠ΅λ‹ˆλ‹€. 이진 탐색은 ν˜„μž¬ λ…Έλ“œμ˜ κ°’κ³Ό 찾고자 ν•˜λŠ” 값을 λΉ„κ΅ν•˜μ—¬ μ™Όμͺ½ λ˜λŠ” 였λ₯Έμͺ½ μ„œλΈŒνŠΈλ¦¬λ‘œ μ΄λ™ν•˜λ©΄μ„œ νƒμƒ‰ν•©λ‹ˆλ‹€. 이둜 인해 탐색 μ‹œκ°„μ€ O(log n)의 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό κ°€μ§‘λ‹ˆλ‹€.
  • μ‚½μž…: νŠΈλ¦¬μ— μƒˆλ‘œμš΄ 값을 μ‚½μž…ν•  λ•ŒλŠ” 탐색을 톡해 값을 μ‚½μž…ν•  μœ„μΉ˜λ₯Ό 찾은 후에 ν•΄λ‹Ή μœ„μΉ˜μ— λ…Έλ“œλ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€. μ΄λ•Œ μ‚½μž… μœ„μΉ˜λŠ” μ μ ˆν•œ 값을 μœ μ§€ν•˜κΈ° μœ„ν•΄ 이진 νƒμƒ‰μ˜ 속성을 μœ μ§€ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • μ‚­μ œ: νŠΈλ¦¬μ—μ„œ 값을 μ‚­μ œν•  λ•ŒλŠ” μ„Έ 가지 경우λ₯Ό κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€. 첫째, μ‚­μ œν•  λ…Έλ“œκ°€ 단말 λ…Έλ“œμΈ 경우 ν•΄λ‹Ή λ…Έλ“œλ₯Ό κ·Έλƒ₯ μ‚­μ œν•©λ‹ˆλ‹€. λ‘˜μ§Έ, μ‚­μ œν•  λ…Έλ“œκ°€ ν•˜λ‚˜μ˜ μ„œλΈŒνŠΈλ¦¬λ₯Ό κ°–λŠ” 경우 μ‚­μ œν•  λ…Έλ“œλ₯Ό κ·Έ μ„œλΈŒνŠΈλ¦¬λ‘œ λŒ€μ²΄ν•©λ‹ˆλ‹€. μ…‹μ§Έ, μ‚­μ œν•  λ…Έλ“œκ°€ 두 개의 μ„œλΈŒνŠΈλ¦¬λ₯Ό κ°–λŠ” 경우 μ‚­μ œν•  λ…Έλ“œμ˜ μ™Όμͺ½ μ„œλΈŒνŠΈλ¦¬μ—μ„œ κ°€μž₯ 큰 값을 μ°Ύμ•„ μ‚­μ œν•  λ…Έλ“œλ‘œ λŒ€μ²΄ν•˜κ±°λ‚˜, 였λ₯Έμͺ½ μ„œλΈŒνŠΈλ¦¬μ—μ„œ κ°€μž₯ μž‘μ€ 값을 μ°Ύμ•„ λŒ€μ²΄ν•©λ‹ˆλ‹€.

currentNode.left

  • currentNode.leftλŠ” 이진 νŠΈλ¦¬μ—μ„œ ν˜„μž¬ λ…Έλ“œ(currentNode)의 μ™Όμͺ½ μžμ‹ λ…Έλ“œλ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ§ν¬λ‚˜ ν¬μΈν„°μž…λ‹ˆλ‹€. 이 λ§ν¬λŠ” ν˜„μž¬ λ…Έλ“œμ™€ μ™Όμͺ½ μžμ‹ λ…Έλ“œλ₯Ό μ—°κ²°ν•©λ‹ˆλ‹€. - 이진 트리의 각 λ…Έλ“œλŠ” μ΅œλŒ€ 두 개의 μžμ‹μ„ κ°€μ§ˆ 수 μžˆμœΌλ―€λ‘œ, **currentNode.left**λŠ” μ™Όμͺ½ μžμ‹ λ…Έλ“œκ°€ μ‘΄μž¬ν•  경우 ν•΄λ‹Ή λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” λ§ν¬μž…λ‹ˆλ‹€. μ™Όμͺ½ μžμ‹ λ…Έλ“œκ°€ 없을 경우 **currentNode.left**λŠ” 보톡 **null**μ΄λ‚˜ λΉ„μ–΄ μžˆλŠ” 값을 κ°€μ§€κ²Œ λ©λ‹ˆλ‹€. - 이 링크λ₯Ό 톡해 μ™Όμͺ½ μžμ‹ λ…Έλ“œμ— μ ‘κ·Όν•  수 있으며, μ™Όμͺ½ μžμ‹ λ…Έλ“œμ˜ κ°’μ΄λ‚˜ ν•΄λ‹Ή μžμ‹ λ…Έλ“œμ˜ ν•˜μœ„ μžμ‹ λ…Έλ“œμ— μ ‘κ·Όν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 접근을 톡해 트리의 ꡬ쑰λ₯Ό νƒμƒ‰ν•˜κ³ , μ›ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • μ•„λž˜λŠ” 이진 νŠΈλ¦¬μ—μ„œ **currentNode.left**λ₯Ό μ‹œκ°μ μœΌλ‘œ ν‘œν˜„ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€:

            A
           / \
          B   C
         / \
        D   E
    
    currentNode: B
    
          (currentNode)
             B
            / \
    (currentNode.left) D   E
    
    
    • μœ„ μ˜ˆμ‹œμ—μ„œ **currentNode**κ°€ B인 경우, **currentNode.left**λŠ” Dλ₯Ό κ°€λ¦¬ν‚΅λ‹ˆλ‹€. λ”°λΌμ„œ **currentNode.left**λ₯Ό 톡해 B의 μ™Όμͺ½ μžμ‹ λ…Έλ“œμΈ D에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

currentNode.right

  • currentNode.rightλŠ” 이진 νŠΈλ¦¬μ—μ„œ ν˜„μž¬ λ…Έλ“œ(currentNode)의 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œλ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ§ν¬λ‚˜ ν¬μΈν„°μž…λ‹ˆλ‹€. 이 λ§ν¬λŠ” ν˜„μž¬ λ…Έλ“œμ™€ 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œλ₯Ό μ—°κ²°ν•©λ‹ˆλ‹€.

    • 이진 트리의 각 λ…Έλ“œλŠ” μ΅œλŒ€ 두 개의 μžμ‹μ„ κ°€μ§ˆ 수 μžˆμœΌλ―€λ‘œ, **currentNode.right**λŠ” 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œκ°€ μ‘΄μž¬ν•  경우 ν•΄λ‹Ή λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” λ§ν¬μž…λ‹ˆλ‹€. 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œκ°€ 없을 경우 **currentNode.right**λŠ” 보톡 **null**μ΄λ‚˜ λΉ„μ–΄ μžˆλŠ” 값을 κ°€μ§€κ²Œ λ©λ‹ˆλ‹€.
    • 이 링크λ₯Ό 톡해 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œμ— μ ‘κ·Όν•  수 있으며, 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œμ˜ κ°’μ΄λ‚˜ ν•΄λ‹Ή μžμ‹ λ…Έλ“œμ˜ ν•˜μœ„ μžμ‹ λ…Έλ“œμ— μ ‘κ·Όν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 접근을 톡해 트리의 ꡬ쑰λ₯Ό νƒμƒ‰ν•˜κ³ , μ›ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ•„λž˜λŠ” 이진 νŠΈλ¦¬μ—μ„œ **currentNode.right**λ₯Ό μ‹œκ°μ μœΌλ‘œ ν‘œν˜„ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€:

            A
           / \
          B   C
         / \
        D   E
    
    currentNode: B
    
          (currentNode)
             B
            / \
           D   E
                  \
                   (currentNode.right) E's right
    
    
    • μœ„ μ˜ˆμ‹œμ—μ„œ **currentNode**κ°€ B인 경우, **currentNode.right**λŠ” Eλ₯Ό κ°€λ¦¬ν‚΅λ‹ˆλ‹€. λ”°λΌμ„œ **currentNode.right**λ₯Ό 톡해 B의 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œμΈ E에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, E의 였λ₯Έμͺ½ μžμ‹ λ…Έλ“œμΈ E's right에도 **currentNode.right.right**λ₯Ό 톡해 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

NextPage