๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“š Algorithm/Algorithm Note

์•Œ๊ณ ๋ฆฌ์ฆ˜ - Binary Search Tree / Tree (์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ, ํŠธ๋ฆฌ, ์ด์ง„ ํŠธ๋ฆฌ, Python ์ฝ”๋“œ)

ํŠธ๋ฆฌ (Tree)

ํŠธ๋ฆฌ (Tree)๋ž€ ๋…ธ๋“œ๋“ค์ด ๋‚˜๋ฌด ๊ฐ€์ง€์ฒ˜๋Ÿผ ์—ฐ๊ฒฐ๋œ ๋น„์„ ํ˜• ๊ณ„์ธต์  ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

ํŠธ๋ฆฌ๋Š” ํŠธ๋ฆฌ ๋‚ด์— ๋‹ค๋ฅธ ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐ€ ์žˆ๊ณ  ๊ทธ ํ•˜์œ„ ํŠธ๋ฆฌ ์•ˆ์—๋Š” ๋˜ ๋‹ค๋ฅธ ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐ€ ์žˆ๋Š” ์žฌ๊ท€์  ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค. 

 

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ์˜ˆ์‹œ

 

 

ํŠธ๋ฆฌ (Tree)์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์šฉ์–ด

- ๋…ธ๋“œ (Node)

ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์žˆ๋Š” ๊ธฐ๋ณธ ์š”์†Œ

 

 

-  ๊ฐ„์„  (Edge)

๋…ธ๋“œ์™€ ๋…ธ๋“œ ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ 

 

 

-  ๋ฃจํŠธ๋…ธ๋“œ (Root Node)

ํŠธ๋ฆฌ ๊ตฌ์กฐ์—์„œ ๋ถ€๋ชจ๊ฐ€ ์—†๋Š” ์ตœ์ƒ์œ„ ๋…ธ๋“œ

 

 

- ๋ถ€๋ชจ๋…ธ๋“œ (Parent Node)

์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง„ ๋…ธ๋“œ

 

 

-  ์ž์‹๋…ธ๋“œ (Child Node)

๋ถ€๋ชจ ๋…ธ๋“œ์˜ ํ•˜์œ„ ๋…ธ๋“œ

 

 

-  ํ˜•์ œ๋…ธ๋“œ (Sibling Node)

๊ฐ™์€ ๋ถ€๋ชจ๋ฅผ ๊ฐ€์ง€๋Š” ๋…ธ๋“œ

 

 

- ์™ธ๋ถ€ ๋…ธ๋“œ(external node, outer node), ๋‹จ๋ง ๋…ธ๋“œ (terminal node), ๋ฆฌํ”„ ๋…ธ๋“œ(leaf node)

์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๋…ธ๋“œ

 

 

 - ๋‚ด๋ถ€ ๋…ธ๋“œ (internal node, inner node), ๋น„ ๋‹จ๋ง ๋…ธ๋“œ (non-terminal node), ๊ฐ€์ง€ ๋…ธ๋“œ (branch node)

์ž์‹ ๋…ธ๋“œ ํ•˜๋‚˜ ์ด์ƒ ๊ฐ€์ง„ ๋…ธ๋“œ

 

 

- ๋†’์ด (height)

์–ด๋–ค ๋…ธ๋“œ์—์„œ ๋ฆฌํ”„ ๋…ธ๋“œ๊นŒ์ง€ ๊ฐ€์žฅ ๊ธด ๊ฒฝ๋กœ์˜ ๊ฐ„์„ (Edge) ์ˆ˜

 

 

- ๊นŠ์ด (depth)

๋ฃจํŠธ์—์„œ ์–ด๋–ค ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฐ„์„ (Edge) ์ˆ˜

 

 

 

ํŠธ๋ฆฌ์˜ ํŠน์ง•

1. ํ•˜๋‚˜์˜ ๋ฃจํŠธ ๋…ธ๋“œ์™€ 0๊ฐœ ์ด์ƒ์˜ ํ•˜์œ„ ํŠธ๋ฆฌ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

2. ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ €์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋น„์„ ํ˜• ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค. 

3. ํŠธ๋ฆฌ ๋‚ด์— ๋˜ ๋‹ค๋ฅธ ํŠธ๋ฆฌ๊ฐ€ ์žˆ๋Š” ์žฌ๊ท€์  ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค. 

4. ๋‹จ์ˆœ ์ˆœํ™˜์„ ๊ฐ–์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐ๋œ ๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ ๊ตฌ์กฐ์ด๋‹ค. 

5. ๋…ธ๋“œ ๊ฐ„์— ๋ถ€๋ชจ ์ž์‹ ๊ด€๊ณ„๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ณ„์ธตํ˜• ์ž๋ฃŒ๊ตฌ์กฐ์ด๋ฉฐ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ๋Š” ํ•˜๋‚˜์˜ ๋ถ€๋ชจ ๋…ธ๋“œ๋งŒ ๊ฐ–๋Š”๋‹ค.

6. ๋…ธ๋“œ๊ฐ€ n๊ฐœ์ธ ํŠธ๋ฆฌ๋Š” ํ•ญ์ƒ n-1๊ฐœ์˜ ๊ฐ„์„ (edge)์„ ๊ฐ€์ง„๋‹ค. 

 

 

ํŠธ๋ฆฌ์˜ ์ข…๋ฅ˜

- ํŽธํ–ฅ ํŠธ๋ฆฌ

๋ชจ๋“  ๋…ธ๋“œ๋“ค์ด ์ž์‹์„ ํ•˜๋‚˜๋งŒ ๊ฐ€์ง„ ํŠธ๋ฆฌ 

 

- ์ด์ง„ ํŠธ๋ฆฌ

๊ฐ ๋…ธ๋“œ์˜ ์ฐจ์ˆ˜(์ž์‹ ๋…ธ๋“œ)๊ฐ€ 2 ์ดํ•˜์ธ ํŠธ๋ฆฌ

 

- ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ

์ˆœ์„œํ™”๋œ ์ด์ง„ ํŠธ๋ฆฌ

๋…ธ๋“œ์˜ ์™ผ์ชฝ ์ž์‹์€ ๋ถ€๋ชจ์˜ ๊ฐ’๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•˜๋ฉฐ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ์ž์‹์€ ๋ถ€๋ชจ์˜ ๊ฐ’๋ณด๋‹ค ํฐ ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

 

- ๊ท ํ˜• ํŠธ๋ฆฌ

๋†’์ด ๊ท ํ˜•์„ ์œ ์ง€ํ•˜๋Š” ํŠธ๋ฆฌ

 

 

Python์œผ๋กœ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ

class Node:
    def __init__(self,value):#์ด์ง„ํŠธ๋ฆฌ์ด๋ฏ€๋กœ left์™€ right๋งŒ ์žˆ์–ด๋„ ๋จ
        self.value = value
        self.left = None
        self.right = None
 
class NodeMgmt:
    def __init__(self,head): #root๋…ธ๋“œ๊ฐ€ head
        self.head=head
        
    # ์‚ฝ์ž… ํ•จ์ˆ˜
    def insert(self,value):
        self.current_node = self.head #ํ˜„์žฌ ๋…ธ๋“œ๋Š” head๋กœ ์žก์Œ
        while True: #recursive
            if value < self.current_node.value: 
                if self.current_node.left != None: 
                    self.current_node = self.current_node.left
                else: 
                    self.current_node.left = Node(value)
                    break

            else:
                if self.current_node.right != None: 
                    self.current_node = self.current_node.right
                else:
                    self.current_node.right = Node(value)
                    break
    # ๊ฒ€์ƒ‰ ํ•ฉ์ˆ˜
    def search(self, value):
        self.current_node = self.head #ํ˜„์žฌ ๋…ธ๋“œ๋Š” head๋กœ ์žก์Œ
        
        while self.current_node: 
            if self.current_node.value == value: 
                return True
                break
            elif value < self.current_node.value:
                self.current_node = self.current_node.left
            else:
                self.current_node = self.current_node.right
        return False    
    
    # ์‚ญ์ œ ํ•จ์ˆ˜
    def delete(self, value):
        searched = False
        self.current_node = self.head
        self.parent = self.head
        
        # ์‚ญ์ œํ•˜๊ณ ์ž ํ•˜๋Š” value๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜์—ฌ current_node๋กœ ์„ค์ •
        
        while self.current_node:
            if self.current_node.value == value:
                searched = True
                break 
            
            elif value < current_node.value:
                self.parent = self.current_node
                self.current_node = self.current_node.left
            else: 
                self.parent = self.current_node
                self.current_node = self.current_node.right
            
        if searched == False:
            return False
    

        if self.current_node.left == None and self.current_node.right==None:
            if value<self.parent.value:
                self.parent.left = None
            else:
                self.parent.right = None
            del self.current_node
        # ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ๋งŒ ์žˆ์„ ๋•Œ
        if self.current_node.left != None and self.current_node.right==None:
            if vale<self.parent.value: 
                self.parent.left = self.current_node.left
            else: 
                self.parent.right = self.current_node.left
        #์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ๋งŒ ์žˆ์„ ๋•Œ
        elif self.current_node.left == None and self.current_node.right!=None:
            if value<self.parent.value:
                self.parent.left = self.current_node.right
            else:
                self.parent.right = self.current_node.right
            
        #child๊ฐ€ ๋‘ ๊ฐœ ์žˆ์„ ๋•Œ
        if self.current_node.left != None and self.current_node.right != None:
            if value<self.parent.value: #3-1
                self.change_node = self.current_node.right
                self.change_node_parent = self.current_node.right
                while self.change_node.left != None:
                    self.change_node.parent = self.change_node
                    self.change_node = self.change_node.left
                
                if self.change_node.right != None: #3-1-2
                    self.change_node_parent.left = self.change_node.right
                else:
                    self.change_node_parent.left = None
                
                self.parent.left = self.change_node
                self.change_node.right = self.current_node.right
                self.change_node.left = self.change_node.left
            
            else:
                self.change_node = self.current_node.right
                self.change_node_parent = self.current_node.right
                while self.change_node.left != None:
                    self.change_node_parent = self.change_node
                    self.change_node = self.change_node.left
                if self.change_node.right != None:
                    self.change_node_parent.left = self.change_node.right
                else:
                    self.change_node_parent.left = None
                self.parent.right = self.change_node
                self.change_node.left = self.current_node.left
                self.change_node.right = self.current_node.right
728x90