Python에서 이진 검색 트리 작성 - 예제 포함

게시물Writing a Binary Search Tree in Python – With Examples은 Qvault에 처음 등장했습니다.
이진 검색 트리 또는 줄여서 BST는 각 노드가 모든 왼쪽 자식 노드보다 크고 모든 오른쪽 자식 노드보다 작은 키를 저장하는 트리입니다. 이진 트리는 조직적인 방식으로 데이터를 저장하는 데 유용하므로 데이터를 빠르게 가져오고, 삽입하고, 업데이트하고, 삭제할 수 있습니다. 노드의 보다 큼 및 보다 작음 순서는 각 비교가 나머지 트리의 약 절반을 건너뛰므로 전체 조회에 트리의 노드 수에 비례하는 시간이 걸린다는 것을 의미합니다.
정확하게 말하면 이진 검색 트리는 검색, 삽입, 업데이트 및 삭제 작업에 대해 평균 Big-O 복잡성
O(log(n))을 제공합니다. Log(n)은 정렬되지 않은 배열에서 항목을 찾는 데 필요한 선형O(n) 시간보다 훨씬 빠릅니다. PostgreSQL 및 MySQL과 같은 널리 사용되는 많은 프로덕션 데이터베이스는 내부에서 이진 트리를 사용하여 CRUD 작업 속도를 높입니다.
BST1단계 – BSTNode 클래스
우리의 구현은
Tree 클래스를 사용하지 않고 대신 Node 클래스만 사용합니다. 이진 트리는 실제로 각 하위 노드에 연결되는 루트 노드에 대한 포인터일 뿐이므로 해당 아이디어로 실행할 것입니다.먼저 생성자를 만듭니다.
class BSTNode:
def __init__ (self, val=None):
self.left = None
self.right = None
self.val = val
값(키)을 제공하도록 허용하지만 제공되지 않으면 그냥
None 로 설정합니다. 또한 새 노드의 두 자식을 None 로 초기화합니다.2단계 – 삽입
새 데이터를 삽입할 방법이 필요합니다. 삽입 방법은 다음과 같습니다.
def insert(self, val):
if not self.val:
self.val = val
return
if self.val == val:
return
if val < self.val:
if self.left:
self.left.insert(val)
return
self.left = BSTNode(val)
return
if self.right:
self.right.insert(val)
return
self.right = BSTNode(val)
노드에 아직 값이 없으면 주어진 값을 설정하고 반환할 수 있습니다. 또한 존재하는 값을 삽입하려고 하면
noop 로 간주될 수 있으므로 간단히 반환할 수도 있습니다. 주어진 값이 노드의 값보다 작고 이미 왼쪽 자식이 있는 경우 왼쪽 자식에서 재귀적으로 insert를 호출합니다. 아직 왼쪽 자식이 없으면 주어진 값을 새로운 왼쪽 자식으로 만듭니다. 우리는 오른쪽에 대해서도 똑같이 할 수 있습니다.3단계 – 최소값 가져오기 및 최대값 가져오기
def get_min(self):
current = self
while current.left is not None:
current = current.left
return current.val
def get_max(self):
current = self
while current.right is not None:
current = current.right
return current.val
getMin 및 getMax는 유용한 도우미 함수이며 작성하기 쉽습니다! 트리의 가장자리를 순회하여 트리에 저장된 가장 작은 값 또는 가장 큰 값을 찾는 간단한 재귀 함수입니다.4단계 – 삭제
def delete(self, val):
if self == None:
return self
if val < self.val:
self.left = self.left.delete(val)
return self
if val > self.val:
self.right = self.right.delete(val)
return self
if self.right == None:
return self.left
if self.left == None:
return self.right
min_larger_node = self.right
while min_larger_node.left:
min_larger_node = min_larger_node.left
self.val = min_larger_node.val
self.right = self.right.delete(min_larger_node.val)
return selfdef delete(self, val):
if self == None:
return self
if val < self.val:
if self.left:
self.left = self.left.delete(val)
return self
if val > self.val:
if self.right:
self.right = self.right.delete(val)
return self
if self.right == None:
return self.left
if self.left == None:
return self.right
min_larger_node = self.right
while min_larger_node.left:
min_larger_node = min_larger_node.left
self.val = min_larger_node.val
self.right = self.right.delete(min_larger_node.val)
return selfdef delete(self, val):
if self == None:
return self
if val < self.val:
self.left = self.left.delete(val)
return self
if val > self.val:
self.right = self.right.delete(val)
return self
if self.right == None:
return self.left
if self.left == None:
return self.right
min_larger_node = self.right
while min_larger_node.left:
min_larger_node = min_larger_node.left
self.val = min_larger_node.val
self.right = self.right.delete(min_larger_node.val)
return self
삭제 작업은 더 복잡한 작업 중 하나입니다. 재귀 함수이기도 하지만 삭제 작업을 수행한 후 주어진 노드의 새로운 상태를 반환하기도 합니다. 이렇게 하면 자식이 삭제된 부모가
left 또는 right 데이터 멤버를 None 로 적절하게 설정할 수 있습니다.5단계 – 존재
exists 함수는 주어진 값이 트리에 이미 존재하는지 여부에 따라
True 또는 False를 반환하는 또 다른 간단한 재귀 함수입니다.def exists(self, val):
if val == self.val:
return True
if val < self.val:
if self.left == None:
return False
return self.left.exists(val)
if self.right == None:
return False
return self.right.exists(val)
6단계 - 순서대로
트리를 읽을 수 있는 형식으로 인쇄할 수 있으면 유용합니다.
inorder 메서드는 키 순서대로 트리의 값을 인쇄합니다.def inorder(self, vals):
if self.left is not None:
self.left.inorder(vals)
if self.val is not None:
vals.append(self.val)
if self.right is not None:
self.right.inorder(vals)
return vals
7단계 – 선주문
def preorder(self, vals):
if self.val is not None:
vals.append(self.val)
if self.left is not None:
self.left.preorder(vals)
if self.right is not None:
self.right.preorder(vals)
return vals
8단계 - 후주문
def postorder(self, vals):
if self.left is not None:
self.left.postorder(vals)
if self.right is not None:
self.right.postorder(vals)
if self.val is not None:
vals.append(self.val)
return vals
용법
def main():
nums = [12, 6, 18, 19, 21, 11, 3, 5, 4, 24, 18]
bst = BSTNode()
for num in nums:
bst.insert(num)
print("preorder:")
print(bst.preorder([]))
print("#")
print("postorder:")
print(bst.postorder([]))
print("#")
print("inorder:")
print(bst.inorder([]))
print("#")
nums = [2, 6, 20]
print("deleting " + str(nums))
for num in nums:
bst.delete(num)
print("#")
print("4 exists:")
print(bst.exists(4))
print("2 exists:")
print(bst.exists(2))
print("12 exists:")
print(bst.exists(12))
print("18 exists:")
print(bst.exists(18))
Python의 전체 이진 검색 트리
class BSTNode:
def __init__ (self, val=None):
self.left = None
self.right = None
self.val = val
def insert(self, val):
if not self.val:
self.val = val
return
if self.val == val:
return
if val < self.val:
if self.left:
self.left.insert(val)
return
self.left = BSTNode(val)
return
if self.right:
self.right.insert(val)
return
self.right = BSTNode(val)
def get_min(self):
current = self
while current.left is not None:
current = current.left
return current.val
def get_max(self):
current = self
while current.right is not None:
current = current.right
return current.val
def delete(self, val):
if self == None:
return self
if val < self.val:
if self.left:
self.left = self.left.delete(val)
return self
if val > self.val:
if self.right:
self.right = self.right.delete(val)
return self
if self.right == None:
return self.left
if self.left == None:
return self.right
min_larger_node = self.right
while min_larger_node.left:
min_larger_node = min_larger_node.left
self.val = min_larger_node.val
self.right = self.right.delete(min_larger_node.val)
return self
def exists(self, val):
if val == self.val:
return True
if val < self.val:
if self.left == None:
return False
return self.left.exists(val)
if self.right == None:
return False
return self.right.exists(val)
def preorder(self, vals):
if self.val is not None:
vals.append(self.val)
if self.left is not None:
self.left.preorder(vals)
if self.right is not None:
self.right.preorder(vals)
return vals
def inorder(self, vals):
if self.left is not None:
self.left.inorder(vals)
if self.val is not None:
vals.append(self.val)
if self.right is not None:
self.right.inorder(vals)
return vals
def postorder(self, vals):
if self.left is not None:
self.left.postorder(vals)
if self.right is not None:
self.right.postorder(vals)
if self.val is not None:
vals.append(self.val)
return vals
읽어 주셔서 감사합니다!
테이크computer science courses on our new platform
질문이나 의견이 있으면 Twitter를 팔로우하고 연락하십시오.
Subscribe 더 많은 프로그래밍 기사를 보려면 뉴스레터로
관련 읽기
Reference
이 문제에 관하여(Python에서 이진 검색 트리 작성 - 예제 포함), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bootdotdev/writing-a-binary-search-tree-in-python-with-examples-2dbe텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)