Krafton_Jungle/Study
Krafton_jungle 5기 13일차 TIL - B-Tree, 알고리즘
전낙타
2024. 3. 30. 21:22
자료구조
B-Tree
B트리란? | B트리는 디스크나 다른 직접 접근 보조 기억장치에서 잘 동작하도록 설계된 균형잡힌 트리이다. |
B트리의 특징 | 이진트리와 다르게 하나의 노드에 여러개의 값을 가질 수 있다. 최대 M(B트리의 차수)개의 자식노드를 가질 수 있다. 3차 B트리라면 3개의 자식을 가질 수 있다.(leaf 노드 제외) 각 노드는 ⌈M/2⌉개의 key를 저장한다. |
데이터 삽입 | 추가는 항상 leaf에 삽입한다. 노드가 넘치면 가운데 key를 기준으로 좌우 key들을 분리하고 다운데 key는 승진한다. |
노드가 넘친다? | 각 노드가 가질 수 있는 최대 M-1개의key를 초과한 경우를 뜻함 |
데이터 삭제 | 데이터의 삭제는 리프 노드에서만 이루어진다. 여기서 리프 노드가 아닌 노드에서 삭제를 시도할 경우, 가장 좌측 자식 노드로 한번 이동한 후 그 뒤로는 쭉 가장 큰 값을 지닌 노드로 내려간다. 이 후 리프노드에 도달하게 되면 해당 노드의 가장 큰 값과 삭제하려는 노드를 스왑하고 삭제한다. 이렇게 스왑하는 이유는 삭제하려는 노드의 가장 근삿값과 스왑하려는 의미를 담고있는 것 같다. 그 후 B-tree의 법칙에 위배되지 않게 노드를 정렬. https://cs.usfca.edu/~galles/visualization/BTree.html 정렬 과정은 위 시뮬레이션을 통해 이해하는게 빠르다. |
알고리즘 문제풀이
1991 트리순회
import sys
N = int(sys.stdin.readline().strip())
tree = {}
for n in range(N):
root, left, right = sys.stdin.readline().strip().split()
tree[root] = [left, right]
def preorder(root):
if root != '.':
print(root, end='') # root
preorder(tree[root][0]) # left
preorder(tree[root][1]) # right
def inorder(root):
if root != '.':
inorder(tree[root][0]) # left
print(root, end='') # root
inorder(tree[root][1]) # right
def postorder(root):
if root != '.':
postorder(tree[root][0]) # left
postorder(tree[root][1]) # right
print(root, end='') # root
preorder('A')
print()
inorder('A')
print()
postorder('A')
처음 전위순회 중위순회 후위순회의 기준을 몰라서 결국 답지를 본 문제.
답지를 보고 나서 하노이 풀었을때 그 이상으로 허무했다.
5639 이진 검색 트리
import sys
sys.setrecursionlimit(20_000)
input = sys.stdin.readline
class Node:
def __init__(self, data):
# double linked list
self.data = data
self.left = None
self.right = None
class binary_search_tree:
def __init__(self):
self.root = None # 루트노드
def __insert__(self, data):
if self.root is None:
self.root = Node(data)
return
node = self.root
while node is not None:
parent = node
if node.data > data:
node = node.left
else:
node = node.right
if parent.data == data:
return
if parent.data > data:
parent.left = Node(data)
else:
parent.right = Node(data)
def postorder(self):
root = self.root
def postorder(root):
if root is None:
return
if root != None:
postorder(root.left) # left
postorder(root.right) # left
print(root.data) # root
postorder(root)
# 실행
BST = binary_search_tree()
while True:
try:
n = int(input())
BST.__insert__(n)
except:
break
BST.postorder()
이진 검색트리를 그대로 재현하려니깐 생각보다 고민할거리가 많았다.
후위 순회는 앞선 트리 순회의 방법을 그대로 따가져와서 크게 어렵지 않았지만, Node 클래스 정의와 left, right 노드를 설정하는 방법이 생각보다 까다로웠다.
그리고 RecursionError 에러가 계속 발생해서 재귀의 깊이를 조금 줄여줬더니 통과됐다.
나와 같은 문제를 겪은 사람들이 많은 듯 하다.
오늘은 복습에 시간을 많이 써서 많이 공부를 못한것같다.