본문 바로가기
Computer Science/자료구조(Data Structure)

[자료구조] 이진 탐색 트리(BST:Binary Search Tree)

by 컴돈AI 2024. 4. 20.

목차

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

    개념

    • 이진 탐색 트리의 각 노드의 값은 왼쪽 서브트리에 있는 값들보다 커야 하고, 오른쪽 서브트리에 있는 값들보다는 작아야 합니다.
    • 삽입
      • def insert(self, data):
            if self.root is None:
                self.root = Node(data)
            else:
                self._insert(self.root, data)
        
        def _insert(self, parent_node, data):
            if data < parent_node.data:
                if parent_node.left is None:
                    parent_node.left = Node(data)
                else:
                    self._insert(parent_node.left, data)
            else:
                if parent_node.right is None:
                    parent_node.right = Node(data)
                else:
                    self._insert(parent_node.right, data)
    • 검색
      • 목표 값이 노드 값과 같으면 노드를 반환합니다.
      • def search(self,data):
            return self._search(self.root,data)
        
        def _search(self, parent_node,data):
            if parent_node is None:
                return None
            elif parent_node.data == data:
                return parent_node
            elif parent_node.data < data:
                return self._search(parent_node.right,data)
            elif parent_node.data > data:
                return self._search(parent_node.left,data)
    • 삭제
      • 만약 왼쪽 서브트리가 없으면 해당 오른쪽 서브트리의 루트 노드를 해당 자리로 옮겨주면 됩니다.
      • 마찬가지로 오른쪽 서브트리가 없으면 해당 왼쪽 서브트리의 루트 노드를 해당 자리로 옮겨주면 됩니다.
      • 위의 두경우는 이미 정렬이 되어 있는 경우이기 때문에 상관없지만 만약 왼쪽 서브트리와 오른쪽 서브트리가 모두 존재할 경우에는 오른쪽 서브트리 중에 제일 작은 값을 찾아서 삭제된 노드의 위치로 옮겨주어야 합니다.
        • 해당 노드를 찾고 parent.data 에 해당 데이터를 옮기고 나면, 해당 값을 이제 해당 서브트레이서 delete를 다시 진행해주어야 합니다.
      • def delete(self,data):
            self.root = self._delete(self.root,data)
        
        def _delete(self, parent, data):
            if parent is None:
                return None
            elif data < parent.data:
                parent.left = self._delete(parent.left, data)
            elif data > parent.data:
                parent.right = self._delete(parent.right, data)
            elif data == parent.data:
                if parent.left is None:
                    return parent.right
        
                elif parent.right is None:
                    return parent.left
                else:
                    temp = self._minvaluenode(parent.right)
                    parent.data = temp.data
                    parent.right = self._delete(parent.right,temp.data) # 옮겨온 노드 삭제
                return parent
        
        # 해당 서브트리의 가장 작은 값까지 이동
        def _minvaluenode(self,node):
            now_node = node
            while now_node.left:
                now_node = now_node.left
            return now_node
    • 전체 코드
      • class Node:
            def __init__(self, data):
                self.data = data
                self.left = None
                self.right = None
        
        
        class BST:
            def __init__(self):
                self.root = None
        
            def insert(self, data):
                if self.root is None:
                    self.root = Node(data)
                else:
                    self._insert(self.root, data)
        
            def _insert(self, parent, data):
                if data < parent.data:
                    if parent.left is None:
                        parent.left = Node(data)
                    else:
                        self._insert(parent.left, data)
                else:
                    if parent.right is None:
                        parent.right = Node(data)
                    else:
                        self._insert(parent.right, data)
        
            def search(self,data):
                return self._search(self.root,data)
        
            def _search(self, parent, data):
                if parent is None:
                    return None
                elif parent.data == data:
                    return parent
                elif parent.data < data:
                    return self._search(parent.right,data)
                elif parent.data > data:
                    return self._search(parent.left,data)
            
            def delete(self,data):
                self.root = self._delete(self.root,data)
            
            def _delete(self, parent, data):
                if parent is None:
                    return None
                elif data < parent.data:
                    parent.left = self._delete(parent.left, data)
                elif data > parent.data:
                    parent.right = self._delete(parent.right, data)
                elif data == parent.data:
                    if parent.left is None:
                        return parent.right
        
                    elif parent.right is None:
                        return parent.left
                    else:
                        temp = self._minvaluenode(parent.right)
                        parent.data = temp.data
                        parent.right = self._delete(parent.right,temp.data) # 옮겨온 노드 삭제
                    return parent
        
            # 해당 서브트리의 가장 작은 값까지 이동
            def _minvaluenode(self,node):
                now_node = node
                while now_node.left:
                    now_node = now_node.left
                return now_node

    출처