[DS] 이진 검색 트리 (Binary Search Tree)

2022. 12. 20. 18:45·Data structure


이진 검색 트리의 특성

1. 각 노드는 킷 값을 하나씩 갖는다. 각 노드의 킷 값은 모두 다르다.
2. 최상위 레벨에 루트 노드가 있고, 각 노드는 최대 2개의 자식 노드를 갖는다.
3. 임의 노드의 킷 값은 자신의 왼쪽 아래에 있는 모든 노드의 킷 값보다 크고,

    오른쪽 아래에 있는 모든 노드의 킷 값보다 작다.
* 검색 트리의 높이는 효율성에 큰 영향을 미친다.

 

이진 검색 트리의 예



이진 검색 트리 노드의 예

 


1. 원소 검색

 

Search(tNode, x):
	if tNode == None or x == tNode.item:
		return tNode;
	elif x < tNode.item:
		return search(tNode.left, x);
	else:
		return search(tNode.right, x);

 

# 검색
    def search(self, x):
        return self.__searchItem(self.__root, x)
    def __searchItem(self, tNode, x):
        if tNode == None:
            return None
        elif x == tNode.item:
            return tNode 
        elif x < tNode.item:
            return self.__searchItem(tNode.left, x)  
        # 최종 리턴값은 x == tNode.item을 만족하는 tNode이어야 함!!
        else:
            return self.__searchItem(tNode.right, x)




2. 원소 삽입

root <--- insert(root, x)

insert(tNode, x):
	if tNode == None:
		tNode = TreeNode(x, None, None)
	elif x < tNode.item:
		tNode.left <--- insert(tNode.left, x)
	else:
		tNode.right <--- insert(tNode.right, x)
	return tNode;

 

# 삽입
    def insert(self, x):
        self.__root = self.__insertItem(self.__root, x)
    # 직접 리스트로 가서 삽입하는 것이기 때문에 리턴할 것이 아니라 root로 받아주어야 함
    def __insertItem(self, tNode, x):
        if tNode == None:
            tNode = TreeNode(x, None, None)
        elif x < tNode.item:
            tNode.left = self.__insertItem(tNode.left, x)
        else:
            tNode.right = self.__insertItem(tNode.right, x)
        return tNode




3. 원소 삭제

deleteItem  삭제할 노드의 위치를 탐색, 발견한 경우 tNode(=r) <--- deleteNode
deleteNode  삭제할 노드(r)의 자녀를 정리 후 리턴(r 자리에 리턴 값을 넣어 주면 이전의 부모는 사라지는 효과) 하거나 자기자신(r)을 정리후 리턴

# 삭제
    def delete(self, x):
        self.__root =  self.__deleteItem(self.__root, x)
    # 직접 리스트로 가서 삭제하는 것이기 때문에 리턴할 것이 아니라 root로 받아 주어야 함
    def __deleteItem(self, tNode, x):
        if tNode == None:
            return None
        elif x == tNode.item:
            tNode = self.__deleteNode(tNode)
        elif x < tNode.item:
            tNode.left = self.__deleteItem(tNode.left, x)
        else:
            tNode.right = self.__deleteItem(tNode.right, x)
        return tNode
    def __deleteNode(self, tNode):
        # 3가지 Case
        #   1. tNode가 자식이 하나도 없음
        #   2. tNode가 자식이 하나만 있음
        #   3. tNode가 자식이 둘 있음
        if (tNode.left == None) and (tNode.right == None):
            return None
        elif tNode.left == None:
            return tNode.right
        elif tNode.right == None:
            return tNode.left
        else:
            (rtnItem, rtnNode) = self.__deleteMinItem(tNode.right)
            tNode.item = rtnItem
            tNode.right = rtnNode
            return tNode 
    def __deleteMinItem(self, tNode):
        if tNode.left == None:
            return (tNode.item, tNode.right)
        else:
            (rtnItem, rtnNode) = self.__deleteMinItem(tNode.left)
            tNode.left = rtnNode
            return (rtnItem, tNode)





Case 1 : 자식이 없는 경우 -> None을 리턴

 

Case 2 : 자식노드가 1개인 경우 -> 자식 노드를 리턴

Case 3 : 자식 노드가 2개인 경우

r의 오른쪽 서브트리의 최소 원소 노드 s를 찾는다 deleteMinItem
s를 r 자리로 복사하고, s를 삭제한다.


이진 검색 트리의 구현

class TreeNode:
    def __init__(self, item, left, right):
        self.item = item
        self.left = left
        self.right = right

class BinarySearchTree:
    def __init__(self):
        self.__root = None
    
    # 검색
    def search(self, x):
        return self.__searchItem(self.__root, x)
    def __searchItem(self, tNode, x):
        if tNode == None:
            return None
        elif x == tNode.item:
            return tNode 
        elif x < tNode.item:
            return self.__searchItem(tNode.left, x)  
        # 최종 리턴값은 x == tNode.item을 만족하는 tNode이어야 함!!
        else:
            return self.__searchItem(tNode.right, x)

    # 삽입
    def insert(self, x):
        self.__root = self.__insertItem(self.__root, x)
    # 직접 리스트로 가서 삽입하는 것이기 때문에 리턴할 것이 아니라 root로 받아주어야 함
    def __insertItem(self, tNode, x):
        if tNode == None:
            tNode = TreeNode(x, None, None)
        elif x < tNode.item:
            tNode.left = self.__insertItem(tNode.left, x)
        else:
            tNode.right = self.__insertItem(tNode.right, x)
        return tNode
    
    # 삭제
    def delete(self, x):
        self.__root =  self.__deleteItem(self.__root, x)
    # 직접 리스트로 가서 삭제하는 것이기 때문에 리턴할 것이 아니라 root로 받아 주어야 함
    def __deleteItem(self, tNode, x):
        if tNode == None:
            return None
        elif x == tNode.item:
            tNode = self.__deleteNode(tNode)
        elif x < tNode.item:
            tNode.left = self.__deleteItem(tNode.left, x)
        else:
            tNode.right = self.__deleteItem(tNode.right, x)
        return tNode
    def __deleteNode(self, tNode):
        # 3가지 Case
        #   1. tNode가 자식이 하나도 없음
        #   2. tNode가 자식이 하나만 있음
        #   3. tNode가 자식이 둘 있음
        if (tNode.left == None) and (tNode.right == None):
            return None
        elif tNode.left == None:
            return tNode.right
        elif tNode.right == None:
            return tNode.left
        else:
            (rtnItem, rtnNode) = self.__deleteMinItem(tNode.right)
            tNode.item = rtnItem
            tNode.right = rtnNode
            return tNode 
    def __deleteMinItem(self, tNode):
        if tNode.left == None:
            return (tNode.item, tNode.right)
        else:
            (rtnItem, rtnNode) = self.__deleteMinItem(tNode.left)
            tNode.left = rtnNode
            return (rtnItem, tNode)
        
    def isEmpty(self):
        return self.__root == None
    
    def clear(self):
        self.__root = None
        
'Data structure' 카테고리의 다른 글
  • [DS] 해시 테이블 (Hash Table)
  • [DS] 힙 (Heap) - Priority Queue ☑️
  • [DS] AVL 트리 (AVL Tree)
  • [DS] FIFO 큐 (FIFO Queue) ☑️
vysryoo
vysryoo
  • vysryoo
    vysryoo
    vysryoo
  • 전체
    오늘
    어제
    • 분류 전체보기 (129)
      • Python (20)
      • Data structure (12)
      • Algorithm (14)
      • Operating system (18)
      • Programming language theory (12)
      • Computer architecture (6)
      • Softeware engineering (8)
      • Multicore (2)
      • Data Base (3)
      • Problem solving (24)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
vysryoo
[DS] 이진 검색 트리 (Binary Search Tree)
상단으로

티스토리툴바