오늘 배웠습니다: 이진 검색 트리 구성

20543 단어

문제 설명



다음 기능을 사용하여 이진 검색 트리에 대한 BST 클래스를 구현합니다.
  • 값 삽입.
  • 발견된 첫 번째 인스턴스에 적용되는 값 제거.
  • 가치를 찾고 있습니다.

  • 샘플 입력



    tree =      10
               /   \
              1     15
            /   \  /   \
           2    5  13   22
          /         \
         1           14
    

    샘플 결과



    insert(12) = 10
               /   \
              1     15
            /   \  /   \
           2    5  13   22
          /       /   \
         1       12   14
    
    remove(10) = 12
               /   \
              1     15
            /   \  /   \
           2    5  13   22
          /         \
         1           14
    

    코드 #1



    class BST:
        def __init__(self, value):
            self.value = value
            self.left = None
            self.right = None
    
        def insert(self, value):
            # case value == int
            cur_node = self
            while True:
                if value < cur_node.value:
                    if cur_node.left is not None:
                        cur_node = cur_node.left
                    else:
                        cur_node.left = BST(value)
                        return self
                elif value >= cur_node.value:
                    if cur_node.right is not None:
                        cur_node = cur_node.right
                    else:
                        cur_node.right = BST(value)
                        return self
            return self
    
        def contains(self, value):
            if self.find_node(value)[0] is not None:
                return self.find_node(value)[0].value == value
            else:
                return False
    
        def remove(self, value, parent_node=None):
            cur_node = self
            while cur_node is not None:
                if value > cur_node.value:
                    parent_node = cur_node
                    cur_node = cur_node.right
                elif value < cur_node.value:
                    parent_node = cur_node
                    cur_node = cur_node.left
                # case there is duplicate value
                elif cur_node.right is not None and value == cur_node.right.value:
                    parent_node = cur_node
                    cur_node = cur_node.right
                # if cur_node is none, aka value not found, the loop will break here
                else:
                    if parent_node is None:
                        if cur_node.left is not None and cur_node.right is not None:
                            cur_node.value = cur_node.right.get_min_value()
                            cur_node.right.remove(cur_node.value, cur_node)
                        elif cur_node.left is not None and cur_node.right is None:
                            cur_node.value = cur_node.left.value
                            cur_node.right = cur_node.left.right
                            cur_node.left = cur_node.left.left
                            break
                        elif cur_node.left is None and cur_node.right is not None:
                            cur_node.value = cur_node.right.get_min_value()
                            cur_node.right.remove(cur_node.value, cur_node)
                        elif cur_node.left is None and cur_node.right is None:
                            # case trying to remove root node but they have no child
                            break
                    else:
                        if cur_node.left is not None and cur_node.right is not None:
                            cur_node.value = cur_node.right.get_min_value()
                            cur_node.right.remove(cur_node.value, cur_node)
                        elif cur_node.left is not None and cur_node.right is None:
                            cur_node.value = cur_node.left.value
                            cur_node.right = cur_node.left.right
                            cur_node.left = cur_node.left.left
                            break
                        elif cur_node.left is None and cur_node.right is not None:
                            cur_node.value = cur_node.right.get_min_value()
                            cur_node.right.remove(cur_node.value, cur_node)
                        elif cur_node.left is None and cur_node.right is None:
                            # case removing leaf node
                            if parent_node.left == cur_node:
                                parent_node.left = None
                            elif parent_node.right == cur_node:
                                parent_node.right = None
                            break
            return self
    
        def find_node(self, value):
            cur_node = self
            parent_node = cur_node
            while True:
                if value == cur_node.value:
                    return cur_node, parent_node
                elif cur_node.left is None and cur_node.right is None:
                    return None, None
                elif value < cur_node.value:
                    if cur_node.left is not None:
                        parent_node = cur_node
                        cur_node = cur_node.left
                    else:
                        return None, None
                elif value >= cur_node.value:
                    if cur_node.right is not None:
                        parent_node = cur_node
                        cur_node = cur_node.right
                    else:
                        return None, None
    
        def get_min_value(self):
            cur_node = self
            while cur_node.left is not None:
                cur_node = cur_node.left
            return cur_node.value
    
    

    메모


  • 대화형 접근 방식을 사용하면 구현하기가 다소 어렵고 재귀적 접근 방식만큼 직관적이지 않지만 공간 복잡성이 더 좋아집니다.

  • 크레딧


  • 문제 진술에 대한 Algoexpert.
  • 표지 이미지의 토마스 로버트슨(https://unsplash.com/photos/wAKld_0lcmA ).
  • 좋은 웹페이지 즐겨찾기