트리
- Node와 Branch를 이용해서 사이클을 이루지 않도록 구성한 데이터 구조
- 장점 : 탐색 속도를 개선할 수 있음
- 시간복잡도(탐색 시)
- h : depth -> O(h) // depth만큼 탐색
- n개의 노드개수를 가진다면, h = log(n)과 비슷해짐
따라서 시간복잡도는 O(logn) //한번 실행시 50%의 노드를 지운다는 말과 같음
- 하지만 만일, 한쪽으로만 균형잡힌 이진트리가 된다면, 모든 노드를 다 순회해야 하기 때문에 시간복잡도는 O(n)이 됨.
이진트리
이진탐색트리(Binary Search Tree)
- 이진트리 중 부모노드보다 값이 큰 노드는 오른쪽에, 부모노드보다 값이 작은 노드는 왼쪽에
파이썬 객체지향 프로그래밍으로 구현하기
class Node:
def __init__(self,value):
self.value = value
self.right = None
self.left = None
class NodeMgmt:
def __init__(self,head):
self.head=head
def insert(self,value):
self.current_node = 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.curret_node.right
else:
self.current_node.right=Node(value)
break
def search(self,value):
self.currnet_node = head
while self.currnet_node:
if self.currnet_node.value == value:
return True
elif value<self.currnet_node.value:
self.currnet_node=self.curret_note.left
else:
self.currnet_node=self.curret_note.right
return False
이진트리 삭제
- leaf node 삭제
- 삭제할 node의 부모 node가 삭제할 node를 가리키지 않도록 한다.
- child node가 하나인 node 삭제
- 삭제할 node의 부모 node가 삭제할 node의 child node를 가리키도록 한다.
- child node가 두개인 node 삭제
- 삭제할 node의 오른쪽 자식 중, 가장 작은 값(가장 왼쪽)을 삭제할 node의 parent node가 가르키게 한다.
- 만약 가장 작은값 노드가 오른쪽 자식을 가지고 있다면, 그 오른쪽 노드를 가장 작은값 노드의 부모의 왼쪽 브랜치가 되도록 한다.
- 삭제할 node의 왼쪽 자식 중, 가장 큰 값(가장 오른쪽)을 삭제할 node의 parent node가 가르키게 한다.
def delete(self,value):
searched=False
self.current_node=self.head
self.parent=self.head
while self.current_node:
if self.currnet_node.value==value:
searched=True
break
elif value<self.currnet_node.value:
self.cparent=self.current_node
self.currnet_node=self.current_node.left
else:
self.parent=self.current_node
self.currnet_node=self.current_node.right
if searched==False:
return Fasle
if self.currnet_node.left==None and self.currnet_node.right==None:
if value<self.parnet.value:
self.parent.left==None
else:
self.parent.right==None
del self.currnet_node
if self.currnet_node.right==None and self.currnet_node.left!=None:
if value<self.parent.value:
self.parnet.left=self.current_node.left
else: (3)
self.parent.right=self.current_node.left
elif self.currnet_node.right!=None and self.currnet_node.left-=None:
if value<self.parnet.value:
self.parent.left=self.current_node.right
else:
self.parent.right=self.current_node.right
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.change_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.left = self.current_node.left
self.change_node.right = self.current_node.right