일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- git checkout
- 비디오 스트리밍
- 파이썬 코딩테스트
- 멘션 추천 기능
- Next.js
- 부스트캠프
- React ssr
- 프로그래머스
- 네이버 부스트캠프 멤버십
- React.js
- 브라우저 동작
- 씨쁠쁠
- Server Side Rendering
- c++
- 웹크롤링
- 파이썬
- Next/Image 캐싱
- 파이썬 웹크롤링
- PubSub 패턴
- 자바스크립트 객체
- react
- 네이버 부캠
- 네이버 부스트캠프
- 코딩테스트
- 자바스크립트
- 스택
- 자바 프로젝트
- beautifulsoup
- Image 컴포넌트
- 자바스크립트 컴파일
Archives
- Today
- Total
코린이의 개발 일지
[파이썬 자료구조] 이진 탐색 트리 (코드 구현 - 찾기, 순회, 삽입, 제거) 본문
반응형
우선 이진 탐색 트리란,
모든 노드에 대해서,
- 왼쪽 서브트리에 있는 데이터는 모두 현재 노드의 값보다 작고
- 오른쪽 서브트리에 있는 데이터는 모두 현재 노드의 값보다 큰 성질을 만족하는 이진트리
(단, 중복되는 데이터 원소는 없는 것으로 가정)
1. 정렬된 배열을 이용한 이진 탐색과 이진 탐색 트리의 비교
이진 탐색 트리의 장점
- 데이터 원소의 추가, 삭제가 용이
이진 탐색 트리의 단점
- 공간 소요가 크다
- 항상 O(logn)의 탐색 복잡도를 가지는 것이 아니다.
2. 이진 탐색 트리의 추상적 자료구조
- 데이터 표현 - 각 노드는 (key, value) 의 쌍으로
- 키를 이용해서 검색 가능
- 보다 복잡한 데이터 레코드로 확장 가능
- 연산의 정의
- insert (key, data) - 트리에 주어진 데이터 원소를 추가
- remove (key) - 특정 원소를 트리로부터 삭제
- lookup(key) - 특정 원소를 검색
- inorder() - 키의 순서대로 데이터 원소를 나열
- min(), max() - 최소 키, 최대 키를 가지는 원소를 각각 탐색
다른 연산들은 크게 복잡하지 않은데 remove 연산의 경우 경우에 따라 나눠주어야 하기 때문에 꽤 복잡해진다.
remove() 코드 설계
- 키(key)를 이용해서 노드를 찾는다.
- 해당 키의 노드가 없으면, 삭제할 것도 없음
- 찾은 노드의 부모 노드도 알고 있어야함 (아래 2번 때문)
- 찾은 노드를 제거하고도 이진 탐색 트리 성질을 만족하도록 트리의 구조를 정리한다.
인터페이스의 설계
입력: 키(key)
출력: 삭제한 경우 True, 해당 키의 노드가 없는 경우 False
이진 탐색 트리 구조의 유지
삭제되는 노드가
- 말단 (leaf) 노드인 경우
- 그냥 그 노드를 없애면 됨
- 부모 노드의 링크 조정
- 자식을 하나 가지고 있는 경우
- 삭제되는 노드 자리에 그 자식을 대신 배치→ 부모 노드의 링크를 조정
- → 자식이 왼쪽? 오른쪽
- 자식을 둘 가지고 있는 경우
- 삭제되는 노드보다 바로 다음 (큰) 키를 가지는 노드를 찾아 그 노드를 삭제되는 노드 자리에 대신 배치하고 이 노드를 대신 삭제
그렇다면 이제 구현한 코드를 봐보자
class Node:
def __init__(self, key, data):
self.key = key
self.data = data
self.left = None
self.right = None
def insert(self, key, data):
if key < self.key:
if self.left:
self.left.insert(key, data)
else:
self.left = Node(key, data)
elif key > self.key:
if self.right:
self.right.insert(key, data)
else:
self.right = Node(key, data)
else:
raise KeyError('Key %s already exists.' % key)
def lookup(self, key, parent=None):
if key < self.key:
if self.left:
return self.left.lookup(key, self)
else:
return None, None
elif key > self.key:
if self.right:
return self.right.lookup(key, self)
else:
return None, None
else:
return self, parent
def inorder(self):
traversal = []
if self.left:
traversal += self.left.inorder()
traversal.append(self)
if self.right:
traversal += self.right.inorder()
return traversal
def countChildren(self):
count = 0
if self.left:
count += 1
if self.right:
count += 1
return count
class BinSearchTree:
def __init__(self,r):
self.root = r
def insert(self, key, data):
if self.root:
self.root.insert(key, data)
else:
self.root = Node(key, data)
def lookup(self, key):
if self.root:
return self.root.lookup(key)
else:
return None, None
def remove(self, key):
node, parent = self.lookup(key)
if node:
nChildren = node.countChildren()
# The simplest case of no children
if nChildren == 0:
if parent:
if parent.left==node:
parent.left=None
elif parent.right==node:
parent.right=None
else:
self.root=None
# When the node has only one child
elif nChildren == 1:
if node.left:
var=node.left
else:
var=node.right
if parent:
if parent.left==node:
parent.left=var
elif parent.right==node:
parent.right=var
else:
self.root=var
# When the node has both left and right children
else:
parent = node
successor = node.right
while successor.left:
parent=successor
successor=successor.left
node.key = successor.key
node.data = successor.data
if parent.left==successor:
parent.left=successor.right
elif parent.right==successor:
parent.right=successor.right
return True
else:
return False
def inorder(self):
if self.root:
return self.root.inorder()
else:
return []
이진 탐색 트리가 별로 효율적이지 못한 경우
left와 right 양쪽의 균형이 잘 잡혀있지 않으면 선형 탐색에 가까워지기 때문에 효율이 떨어진다.
보다 나은 성능을 보이는 이진 탐색 트리들
→ 높이의 균형을 유지함으로써 O(logn)의 탐색 복잡도 보장
삽입, 삭제 연산이 보다 복잡
아래 트리들을 참고 할 것.
AVL trees
Red-black trees
반응형
'CS공부 > 자료구조' 카테고리의 다른 글
[자료구조] c언어로 스택 구현하기 (0) | 2022.04.16 |
---|---|
[파이썬 자료구조] 힙(Heap) - 개념, 최대힙, 최소힙, 코드 구현 (0) | 2021.09.13 |
[파이썬 자료구조] 이진 트리 (Binary Tree) - 코드 구현(size, depth, travelsal) (0) | 2021.08.30 |
[파이썬 자료구조] 트리(Trees) - 트리의 개념, 이진트리의 개념 (0) | 2021.08.30 |
[파이썬 자료구조] 큐(Queue) - 큐의 활용, 환형큐 구현, 우선순위 큐 구현 (0) | 2021.08.25 |
Comments