알아둘 용어
이진 트리와 이진 탐색 트리 (Binary Search Tree)
자료 구조 이진 탐색 트리의 장점과 주요 용도
파이썬 객체 지향 프로그래밍으로 이진 탐색 트리 구현하기
노드 클래스 만들기
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
이진 탐색 트리에 데이터 넣기
class NodeMgmt:
def __init__(self, head):
self.head = head
def insert(self, value):
self.current_node = self.head
while True:
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
이진 탐색트리의 검색
class NodeMgmt:
def __init__(self, head):
self.head = head
def search(self,value):
self.current_node = self.head
while self.current_node: # current_node가 있는 경우 반복
if self.current_node.value == value: # 현재 생성자의 노드값과 검색할 값이 동일한 경우
return True
elif value < self.current_node.value: # 현재 생성자의 노드값이 검색할 값보다 큰 경우
self.current_node = self.current_node.left # 현재 생성자의 왼쪽값으로 이동
else: # 현재 생성자의 노드값이 검색할 값보다 작은 경우
self.current_node = self.current_node.right # 현재 생성자의 오른쪽 값으로 이동
return False # 찾지 못했을 때
이진 탐색 트리의 삭제
삭제할 노드 탐색
searched = False
self.current_node = self.head
self.parent = self.head
while self.current_node:
if self.current_node.value == value: # 현재 생성자의 노드값과 삭제할 값이 동일한 경우
searched = True
break
elif value < self.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
1-2. 삭제할 노드가 Leaf Node인 경우
# 현재 노드의 왼쪽,오른쪽값이 없을 경우
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 # 부모노드의 오른쪽값 삭제
1-3. Child Node 가 하나인 node를 삭제
# 현재노드값의 왼쪽값이 있고 오른쪽값이 없을 때
if self.current_node.left != None and self.current_node.right == None:
if value < 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.parrent.left = self.current_node.right
else:
self.parent.right = self.current_node.right
1-4. Child Node가 두 개인 Node를 삭제
가장 작은 값을 가진 Node의 Child Node가 왼쪽에 있을 경우는 절대 없음. 있다는 것은 해당 Node보다 더 작은 값을 가진 Node가 존재한다는 뜻이기 때문
1-5. Child Node가 두 개인 Node를 삭제하는 코드 구현하기
# 현재 노드의 왼쪽,오른쪽 값이 있을 때
if self.current_node.left != None and self.current_node.right != None:
if value < self.parent.value: # 부모노드가 삭제할 값보다 큰 경우
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.left = self.change_node # 부모의 왼쪽값을 현재노드로 설정
self.change_node.right = self.current_node.right # 현재노드의 오른쪽값을 삭제할값의 오른쪽값으로 설정
self.change_node.left = self.current_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.right = self.current_node.right
self.change_node.left = self.current_node.left