πŸ‘‰μžλ£Œκ΅¬μ‘°/μ•Œκ³ λ¦¬μ¦˜ - 6

ν•™μŠ΅κΈ°λ‘

였늘 듀은 κ°•μ˜ λͺ©λ‘

  1. 트리 - 1
  2. 트리 - 2
  3. 트리 - 3
  4. 트리 - 4
  5. 트리 - 5

와.. μ›¬λ§Œν•΄μ„œ ν•˜λ£¨μ— ν•œ μ£Όμ œμ”© λλ‚΄λ €κ³ ν–ˆλŠ”λ°
νŠΈλ¦¬κ°€ 8κ°•μ΄λ‚˜ μžˆλ‹€..
이틀에 λ‚˜λˆ μ„œ ν•΄μ•Όκ² λ‹€.

트리

λ‚˜λ¬΄μ²˜λŸΌ 가지에 잎이 λ”Έλ¦° ν˜•νƒœλ‘œ 트리라고 ν•œλ‹€.
Node와 Branch(κ°„μ„ , edge)λ₯Ό μ΄μš©ν•΄μ„œ 사이클이 κ΅¬μ„±λ˜μ§€ μ•Šλ„λ‘ ν˜•μ„±λœ ꡬ쑰

주둜 μ΄μ§„νŠΈλ¦¬ ν˜•νƒœλ‘œ νƒμƒ‰μ•Œκ³ λ¦¬μ¦˜μ— 많이 μ‚¬μš©λœλ‹€.

μš©μ–΄

  • λ…Έλ“œ(Node) : 데이터λ₯Ό μ €μž₯ν•˜λŠ” μš”μ†Œ
  • μ΅œμƒμœ„ λ…Έλ“œ(Root Node) : 트리의 맨 μœ„μ— μžˆλŠ” λ…Έλ“œ
  • 레벨(Level) : 각 λ…Έλ“œμ˜ 깊이λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. μ΅œμƒμœ„ λ…Έλ“œμ˜ λ ˆλ²¨μ€ 0, ν•˜μœ„ node둜 κ°ˆλ•Œλ§ˆλ‹€ 1μ”© μ¦κ°€ν•œλ‹€.
  • 깊이(Depth) : μ΅œν•˜μœ„ λ…Έλ“œμ˜ 레벨
  • μžμ‹ λ…Έλ“œ(Child Node) : μ–΄λ–€ λ…Έλ“œμ— μ—°κ²°λœ λ‹€μŒ 레벨의 λ…Έλ“œ
  • λΆ€λͺ¨ λ…Έλ“œ(Parent Node) : μ–΄λ–€ λ…Έλ“œμ— μ—°κ²°λœ 이전 레벨의 λ…Έλ“œ
  • 잎 λ…Έλ“œ(Leaf Node) : μžμ‹μ΄ μ—†λŠ” λ…Έλ“œ
  • ν˜•μ œ(Siblings) : 같은 λΆ€λͺ¨λ₯Ό κ°€μ§„ λ…Έλ“œλ“€ (μ‚¬μ§„μ—μ„œ 3κ³Ό 6은 ν˜•μ œκ΄€κ³„μ΄λ‹€.)

tree

이진 트리(Binary Tree)

μžμ‹μ„ μ΅œλŒ€ λ‘κ°œκ°–λŠ” 트리

이진 탐색 트리(Binary Search Tree, BST)

μžμ‹μ„ μ΅œλŒ€ λ‘κ°œκ°–λŠ” μ΄μ§„νŠΈλ¦¬μ˜ νŠΉμ§•μ„ κ°€μ§€κ³ ,
μ™Όμͺ½ μžμ‹λ…Έλ“œλŠ” ν˜„μž¬ λ…Έλ“œλ³΄λ‹€ μž‘μ€ κ°’,
였λ₯Έμͺ½ μžμ‹λ…Έλ“œλŠ” ν˜„μž¬ λ…Έλ“œλ³΄λ‹€ 큰 값을 κ°€μ§€λŠ” ꡬ쑰λ₯Ό λ„λŠ” 트리.

μš©λ„ : 데이터 검색 μž₯점 : 탐색 속도 κ°œμ„  단점 : λ³΅μž‘ν•˜λ‹€.

class BinaryNode:
    def __init__(self, value):
        self.value = value
        self.left = None # 쒌츑 μžμ‹μ„ μ—†μŒμœΌλ‘œ μ΄ˆκΈ°ν™”
        self.right = None # 우츑 μžμ‹μ„ μ—†μŒμœΌλ‘œ μ΄ˆκΈ°ν™”
class BinaryTree:
    def __init__(self, head = None):
        self.head = head

μ΄μ§„νƒμƒ‰νŠΈλ¦¬μ—μ„œ 데이터 μ‚½μž…

  1. BST에 μ΅œμƒμœ„ λ…Έλ“œκ°€ μ—†λŠ” 경우 μ΅œμƒμœ„ λ…Έλ“œμ— 데이터λ₯Ό μ‚½μž…ν•˜κ³  μ’…λ£Œν•œλ‹€.
  2. μ΅œμƒμœ„ λ…Έλ“œλΆ€ν„° 탐색을 μ‹œμž‘ν•œλ‹€.
  3. ν˜„μž¬ λ…Έλ“œμ˜ 값보닀 μ‚½μž…ν•˜λ €λŠ” 값이 μž‘λ‹€λ©΄ μ™Όμͺ½ λ…Έλ“œλΆ€ν„° λ‹€μ‹œ 탐색을 μ‹œμž‘ν•˜κ³ ,
    ν˜„μž¬ λ…Έλ“œμ˜ 값보닀 μ‚½μž…ν•˜λ €λŠ” 값이 크닀면 였λ₯Έμͺ½ λ…Έλ“œλΆ€ν„° λ‹€μ‹œ 탐색을 μ‹œμž‘ν•œλ‹€.
  4. λ‹€μŒ νƒμƒ‰μœ„μΉ˜μ— λ…Έλ“œκ°€ μ—†μ„λ•ŒκΉŒμ§€ 2λ²ˆμ„ λ°˜λ³΅ν•œλ‹€.
  5. λ‹€μŒ νƒμƒ‰μœ„μΉ˜μ— 데이터λ₯Ό μ‚½μž…ν•œλ‹€.
def insert(self, value):
    if self.head == None:
        self.head = Node(value)
        return
    current_node = self.head
    while True:
        if value < current_node.value:
            if current_node.left == None:
                current_node.left = Node(value)
                return
            else:
                current_node = current_node.left
        else:
            if current_node.right == None:
                current_node.right = Node(value)
                return
            else:
                current_node = current_node.right

μ΄μ§„νƒ‘μƒ‰νŠΈλ¦¬μ—μ„œ 데이터 탐색

  1. μ΅œμƒμœ„ λ…Έλ“œλΆ€ν„° 탐색을 μ‹œμž‘ν•œλ‹€.
  2. ν˜„μž¬ λ…Έλ“œμ˜ 값보닀 μ‚½μž…ν•˜λ €λŠ” 값이 μž‘λ‹€λ©΄ μ™Όμͺ½ λ…Έλ“œλΆ€ν„° λ‹€μ‹œ 탐색을 μ‹œμž‘ν•˜κ³ ,
    ν˜„μž¬ λ…Έλ“œμ˜ 값보닀 μ‚½μž…ν•˜λ €λŠ” 값이 크닀면 였λ₯Έμͺ½ λ…Έλ“œλΆ€ν„° λ‹€μ‹œ 탐색을 μ‹œμž‘ν•œλ‹€.
  3. 값을 찾을 λ•ŒκΉŒμ§€ 탐색을 κ³„μ†ν•œλ‹€.
  4. 값을 μ°Ύμ•˜λ‹€λ©΄ Trueλ₯Ό λ°˜ν™˜ν•œλ‹€. (이런 경우 반볡문 λ‚΄μ—μ„œ 값을 μ°Ύμ•˜μ„ 것이닀. -> 반볡문 내에 μž‘μ„±)
  5. 값을 μ°Ύμ§€ λͺ»ν•œ 경우 Falseλ₯Ό λ°˜ν™˜ν•œλ‹€. (이런 경우 반볡문이 μ’…λ£Œλ˜μ—ˆμ„ 것이닀. -> ν•¨μˆ˜ μ’…λ£Œμ‹œμ— μž‘μ„±)
def search(self, value):
    current_node = self.head
    while current_node:
        if current_node.value == value:
            return True
        elif value < current_node.value:
            current_node = current_node.left
        else:
            current_node = current_node.right

μ΄μ§„νƒ‘μƒ‰νŠΈλ¦¬μ—μ„œ 데이터 μ‚­μ œ

데이터 μ‚­μ œλŠ” BSTκ΅¬ν˜„μ—μ„œ κ°€μž₯ λ³΅μž‘ν•œ 뢀뢄이닀.
데이터 μ‚­μ œλŠ” μ—¬λŸ¬κ°€μ§€ μΌ€μ΄μŠ€λ‘œ λ‚˜λˆ μ„œ κ΅¬ν˜„ν•˜λŠ” 것이 덜 λ³΅μž‘ν•˜λ‹€.

λ…Έλ“œλ₯Ό μ‚­μ œν•˜κΈ° μœ„ν•΄μ„œλŠ” ν•΄λ‹Ή λ…Έλ“œμ˜ μžλ¦¬μ— λ“€μ–΄κ°ˆ λ‹€λ₯Έ λ…Έλ“œμ™€ ν•΄λ‹Ή λ…Έλ“œμ˜ λΆ€λͺ¨ λ…Έλ“œλ₯Ό μ΄μ–΄μ€˜μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— λ…Έλ“œλ₯Ό νƒμƒ‰ν•˜λ©΄μ„œ λΆ€λͺ¨ λ…Έλ“œ λ˜ν•œ λ”°λ‘œ μ €μž₯ν•΄λ†”μ•Όν•œλ‹€.
또, νƒμƒ‰μ½”λ“œμ™€λŠ” 쑰금 λ‹€λ₯΄κ²Œ μ°Ύμ•˜λŠ”μ§€ μ‘΄μž¬μ—¬λΆ€λ˜ν•œ μ €μž₯해둬야 ν•œλ‹€.

  1. μ‚­μ œν•  λ…Έλ“œκ°€ μ—†λŠ” 경우

Falseλ₯Ό 리턴해쀀닀.
μ‘΄μž¬μ—¬λΆ€λ₯Ό ν™•μΈν•΄μ„œ κ°„λ‹¨ν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€.

  1. μ‚­μ œν•˜κ³ μž ν•˜λŠ” λ…Έλ“œμ— μžμ‹μ΄ μ—†λŠ” 경우(Leaf Node)
    ν•΄λ‹Ή λ…Έλ“œλ₯Ό μ‚­μ œν•˜κ³  λΆ€λͺ¨ λ…Έλ“œμ—μ„œ ν•΄λ‹Ή λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” 뢀뢄을 Noneλ“±μœΌλ‘œ μ΄ˆκΈ°ν™”ν•΄μ€˜μ•Όν•œλ‹€.
    이것 λ˜ν•œ κ°„λ‹¨ν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€.

removeleaf

  1. μ‚­μ œν•˜κ³ μž ν•˜λŠ” λ…Έλ“œμ˜ μžμ‹μ΄ ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜λŠ” 경우
    ν˜„μž¬ λ…Έλ“œμ˜ μœ„μΉ˜λ₯Ό ν˜„μž¬λ…Έλ“œμ˜ μžμ‹λ…Έλ“œλ‘œ λ³€κ²½ν•΄μ£Όλ©΄ λœλ‹€.
    이것 λ˜ν•œ κ°„λ‹¨ν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€.
    (λ‹€λ§Œ, ν˜„μž¬ λ…Έλ“œκ°€ λΆ€λͺ¨ λ…Έλ“œμ˜ μ™Όμͺ½ μžμ‹μΈμ§€ 였λ₯Έμͺ½ μžμ‹μΈμ§€μ— λ”°λΌμ„œλ§Œ μ²˜λ¦¬ν•˜λ©΄ λœλ‹€. μ‹€μˆ˜μ‘°μ‹¬!)
    1child

  2. μ‚­μ œν•˜κ³ μž ν•˜λŠ” λ…Έλ“œμ˜ μžμ‹μ΄ λ‘˜λ‹€ μ‘΄μž¬ν•˜λŠ” 경우(κ°€μž₯볡작)
    BST의 κ΅¬ν˜„μ΄ λ³΅μž‘ν•˜λ‹€κ³  ν•˜λŠ” μ΄μœ μ΄λ‹€.
    두가지 방법이 μ‘΄μž¬ν•˜λŠ”λ°,

    • ν˜„μž¬λ…Έλ“œμ˜ 쒌츑 μžμ‹λ…Έλ“œλ₯Ό 루트둜 ν•˜λŠ” νŠΈλ¦¬μ—μ„œ κ°€μž₯ 큰 값을 ν˜„μž¬ λ…Έλ“œμ˜ μœ„μΉ˜μ— λ³€κ²½
    • ν˜„μž¬λ…Έλ“œμ˜ 우츑 μžμ‹λ…Έλ“œλ₯Ό 루트둜 ν•˜λŠ” νŠΈλ¦¬μ—μ„œ κ°€μž₯ μž‘μ€ 값을 ν˜„μž¬ λ…Έλ“œμ˜ μœ„μΉ˜μ— λ³€κ²½

2child

일뢀 κ΅¬ν˜„

μ•„λž˜λŠ” 데이터 μ‚½μž…, 탐색을 κ΅¬ν˜„ν•œ μ½”λ“œ

class Node:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None
class BST:
    def __init__(self, head = None):
        self.head = head
    
    def insert(self, value):
        if self.head == None:
            self.head = Node(value)
            return
        current_node = self.head
        while True:
            if value < current_node.value:
                if current_node.left == None:
                    current_node.left = Node(value)
                    return
                else:
                    current_node = current_node.left
            else:
                if current_node.right == None:
                    current_node.right = Node(value)
                    return
                else:
                    current_node = current_node.right
                    
    def search(self, value):
        current_node = self.head
        while current_node:
            if current_node.value == value:
                return True
            elif value < current_node.value:
                current_node = current_node.left
            else:
                current_node = current_node.right

μ™„μ „ν•œ κ΅¬ν˜„μ€ λ‹€μŒ ν¬μŠ€νŒ…μ— ν•˜λ„λ‘ ν•˜κ² λ‹€.

λŒ“κΈ€λ‚¨κΈ°κΈ°