2024. 1. 11. 22:36ใCS - Roadmap.sh/1. Data structures
Data structures (with python) - 8.Tree - 8.5 Balanced Tree
๐ก A balanced binary tree, also referred to as a height-balanced binary tree, is defined as a binary tree in which the height of the left and right subtree of any node differ by not more than 1.
๋์ด-๊ท ํ ์ด์ง ํธ๋ฆฌ๋ผ๊ณ ๋ ํ๋ ๊ท ํ ์ด์ง ํธ๋ฆฌ๋ ๋ชจ๋ ๋ ธ๋์ ์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ ํ์ ํธ๋ฆฌ์ ๋์ด๊ฐ 1 ์ดํ๋ก ์ฐจ์ด๊ฐ ๋๋ ์ด์ง ํธ๋ฆฌ๋ก ์ ์๋ฉ๋๋ค.
๊ท ํํธ๋ฆฌ(Balanced Tree)์ ๋ํด ์์๋ด ์๋ค.
๊ท ํ ํธ๋ฆฌ๋ ๋ชจ๋ ๋ ธ๋์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด ์ฐจ๊ฐ ์ต๋ 1์ธ ํน์ง์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ด๋ ๊ฒ ๊ท ํ์ ์ ์งํ๊ฒ ๋๋ฉด, ํธ๋ฆฌ์ ๋์ด๋ฅผ ์ต์ํํ์ฌ ํ์, ์ฝ์ , ์ญ์ ๋ฑ์ ์ฐ์ฐ์ ๋น ๋ฅด๊ฒ ์ํํ ์ ์์ต๋๋ค.
์ด๋ฌํ ๊ท ํ ํธ๋ฆฌ์ ์๋ก๋ AVL ํธ๋ฆฌ, ๋ ๋-๋ธ๋ ํธ๋ฆฌ ๋ฑ์ด ์์ต๋๋ค.
In Python
AVL ํธ๋ฆฌ๋ฅผ ์๋ก ํ์ด์ฌ์์ ๋ฐธ๋ฐ์ค๋ ํธ๋ฆฌ๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
(AVL ํธ๋ฆฌ๋ ์์ฒด ๊ท ํ์ ์ ์งํ๋ ์ด์ง ํ์ ํธ๋ฆฌ์ํ ์ข ๋ฅ์ ๋๋ค.)
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.height = 1
class AVLTree:
def __init__(self):
self.root = None
def insert(self, key):
# ์ฝ๋ ์๋ต...
def delete(self, key):
# ์ฝ๋ ์๋ต...
def search(self, key):
# ์ฝ๋ ์๋ต...
# ์ถ๊ฐ์ ์ธ ๋ฉ์๋(ํ์ , ๋์ด ๊ณ์ฐ, ๊ท ํ ๊ณ์ฐ ๋ฑ)...
์ด๋ฐ ํ์์ผ๋ก ๊ตฌํ๋ฉ๋๋ค.
์๋ต๋ ๋ถ๋ถ์ ์ ๋ง ์์๋ฅผ ๋ค์ด๋ณธ๋ค๋ฉด,
์ฝ์ (insert) ๋ฉ์๋๋ฅผ ๋จผ์ ์์๋ก ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
def insert(self, root, key):
if not root:
return Node(key)
elif key < root.key:
root.left = self.insert(root.left, key)
else:
root.right = self.insert(root.right, key)
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
balance = self.getBalance(root)
if balance > 1:
if key < root.left.key:
return self.rightRotate(root)
else:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
if balance < -1:
if key > root.right.key:
return self.leftRotate(root)
else:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
์์ฝ๋์์ ๋จผ์ ์ด์งํ์ํธ๋ฆฌ์ ์ฝ์ ์ฐ์ฐ์ ์ํํ ๋ค,
๋์ด๋ฅผ ๊ฐฑ์ ํ๊ณ ๊ท ํ์ ํ์ธํฉ๋๋ค.
if balance ๋ฅผ ํตํด ๊ท ํ์ด ๊บ ์ง๋ ๊ฒฝ์ฐ,
์ ์ ํ ์ฐ์ฐ์ ์ํํ์ฌ ๊ท ํ์ ๋ณต์ํฉ๋๋ค.
์ญ์ (delete)
def delete(self, root, key):
if not root:
return root
elif key < root.key:
root.left = self.delete(root.left, key)
elif key > root.key:
root.right = self.delete(root.right, key)
else:
if root.left is None:
temp = root.right
root = None
return temp
elif root.right is None:
temp = root.left
root = None
return temp
temp = self.getMinValueNode(root.right)
root.key = temp.key
root.right = self.delete(root.right,
temp.key)
if root is None:
return root
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
balance = self.getBalance(root)
if balance > 1:
if self.getBalance(root.left) >= 0:
return self.rightRotate(root)
else:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
if balance < -1:
if self.getBalance(root.right) <= 0:
return self.leftRotate(root)
else:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
1. ๋จผ์ ์ญ์ ํ ํค๋ฅผ ๊ฐ์ง ๋ ธ๋๋ฅผ ์ฐพ์ต๋๋ค.
์ด๋ ํค๊ฐ ๋ฃจํธ ๋ ธ๋์ ํค๋ณด๋ค ์์ผ๋ฉด ์ผ์ชฝ ์๋ธํธ๋ฆฌ์์ ์ฐพ๊ณ , ํฌ๋ฉด ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์์ ์ฐพ์ต๋๋ค.
(elif key )
2. ํค๋ฅผ ์ฐพ์๋ค๋ฉด, ํด๋น ๋ ธ๋๋ฅต ์ญ์ ํฉ๋๋ค.
- ์ญ์ ํ ๋ ธ๋๊ฐ ์์ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ: ๊ทธ๋ฅ ์ญ์
- ์ญ์ ํ ๋ ธ๋๊ฐ ํ ๊ฐ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง๋ ๊ฒฝ์ฐ : ์ญ์ ํ ๋ ธ๋๋ฅผ ๊ทธ ์์ ๋ ธ๋๋ก ๋์ฒด
- ์ญ์ ํ ๋ ธ๋๊ฐ ๋ ๊ฐ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง๋ ๊ฒฝ์ฐ : ์ญ์ ํ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์์ ๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ์ง ๋ ธ๋
(์ฆ, ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๊ฐ์ฅ ์ผ์ชพ ๋ ธ๋)๋ฅผ ์ฐพ์์ ์ญ์ ํ ๋ ธ๋์ ์์น์ ๋๊ณ , ๊ทธ ๋ ธ๋๋ฅผ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์์ ์ญ์ ํฉ๋๋ค.
3. ๋ ธ๋๋ฅผ ์ญ์ ํ ํ์๋ ๋์ด๋ฅผ ๊ฐฑ์ , ๊ท ํ์ ํ์ธํฉ๋๋ค.
๊ท ํ์ด ๊นจ์ง๋ ๊ฒฝ์ฐ, ์ ์ ํ ํ์ ์ฐ์ฐ์ ์ํํ์ฌ ๊ท ํ์ ๋ณต์ํฉ๋๋ค.
ํ์ ์ฐ์ฐ์ ์ฝ์ ์ฐ์ฐ ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก, ๊ท ํ์ด ๊บ ์ง ๋ ธ๋์ ์ํ์ ๋ฐ๋ผ ๊ฒฐ์ ๋ฉ๋๋ค.
AVL ํธ๋ฆฌ๋ฅผ ๋ํ๋ด๋ ํด๋์ค๋ฅผ ์์๋ณด์์ต๋๋ค.
์ด๋ฌํ ๊ท ํ ํธ๋ฆฌ๋ ํ์, ์ฝ์ , ์ญ์ ์ฐ์ฐ์ ๋น ๋ฅด๊ฒ ์ํํ ์ ์์ด ๋ค์ํ ์๊ณ ๋ฆฌ์ฆ๊ณผ ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉํฉ๋๋ค.
์๋ก, DB ์์คํ ์์ ๋น ๋ฅธ ํ์ ์๋๋ฅผ ๋ณด์ฅํ๊ธฐ์ํด ์ด๋ฌํ ๊ท ํ ํธ๋ฆฌ๋ฅผ ํ์ฉํฉ๋๋ค.
Appendix
ํ์ ์ฐ์ฐ์ด ๋ญ๋ฐ?
๊ท ํ ํธ๋ฆฌ๋ฅผ ์ค๋ช ํ ๋ ํ์ํ ๊ท ํ์ด ์๋ง์ผ๋ฉด ํ์ ์ฐ์ฐ์ ํตํ์ฌ ๊ท ํ์ ๋ณต๊ตฌํ๋ค๊ณ ๋งํ์์ต๋๋ค.
ํ์ ์ฐ์ฐ์ ๋ญ๊น์?
ํ์ ์ฐ์ฐ์ AVL ํธ๋ฆฌ๊ฐ ๊ท ํ์ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ์ฐ์ฐ์ ๋๋ค.
AVL ํธ๋ฆฌ์์๋ ์ฝ์
์ด๋ ์ญ์ ์ฐ์ฐ์ด ์ด๋ฃจ์ด์ง ๋๋ง๋ค ํธ๋ฆฌ์ ๊ท ํ์ ํ์ธํ๊ณ , ํ์ํ ๊ฒฝ์ฐ ํ์ ์ฐ์ฐ์ ์ํํ์ฌ ๊ท ํ์ ๋ณต์ํฉ๋๋ค. ์ด๋ ํ์ ์ ํฌ๊ฒ ์ผ์ชฝ ํ์ ๊ณผ ์ค๋ฅธ์ชฝ ํ์ , ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ์กฐํฉํ ์ผ์ชฝ-์ค๋ฅธ์ชฝ ํ์ ๊ณผ ์ค๋ฅธ์ชฝ-์ผ์ชฝ ํ์ ์ผ๋ก ๋๋ ์ ์์ต๋๋ค.
์ผ์ชฝ ํ์ : ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์์์ด ๋ถ๋ชจ๊ฐ ๋๊ณ , ์๋์ ๋
ธ๋๋ ๊ทธ ์์์ ์ผ์ชฝ ์์์ด ๋ฉ๋๋ค. ์ด ์ฐ์ฐ์ ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๊ฐ ๋๋ฌด ๋์์ ธ ๊ท ํ์ด ๊นจ์ก์ ๋ ์ฌ์ฉํ๋ฉฐ, ์ด๋ฅผ ํตํด ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
์ค๋ฅธ์ชฝ ํ์ : ๋
ธ๋์ ์ผ์ชฝ ์์์ด ๋ถ๋ชจ๊ฐ ๋๊ณ , ์๋์ ๋
ธ๋๋ ๊ทธ ์์์ ์ค๋ฅธ์ชฝ ์์์ด ๋ฉ๋๋ค. ์ด ์ฐ์ฐ์ ๋
ธ๋์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๊ฐ ๋๋ฌด ๋์์ ธ ๊ท ํ์ด ๊นจ์ก์ ๋ ์ฌ์ฉํ๋ฉฐ, ์ด๋ฅผ ํตํด ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
์ผ์ชฝ-์ค๋ฅธ์ชฝ ํ์ : ๋
ธ๋์ ์ผ์ชฝ ์์์ ๋ํด ์ผ์ชฝ ํ์ ์ ์ํํ ํ, ๋
ธ๋์ ๋ํด ์ค๋ฅธ์ชฝ ํ์ ์ ์ํํฉ๋๋ค. ์ด ์ฐ์ฐ์ ๋
ธ๋์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๊ฐ ๋์์ง ์ํ์์, ๊ทธ ์๋ธํธ๋ฆฌ์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๊ฐ ๋๋ฌด ๋์์ ธ ๊ท ํ์ด ๊นจ์ก์ ๋ ์ฌ์ฉํฉ๋๋ค.
์ค๋ฅธ์ชฝ-์ผ์ชฝ ํ์ : ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์์์ ๋ํด ์ค๋ฅธ์ชฝ ํ์ ์ ์ํํ ํ, ๋
ธ๋์ ๋ํด ์ผ์ชฝ ํ์ ์ ์ํํฉ๋๋ค. ์ด ์ฐ์ฐ์ ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๊ฐ ๋์์ง ์ํ์์, ๊ทธ ์๋ธํธ๋ฆฌ์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๊ฐ ๋๋ฌด ๋์์ ธ ๊ท ํ์ด ๊นจ์ก์ ๋ ์ฌ์ฉํฉ๋๋ค.
์ด๋ฌํ ํ์ ์ฐ์ฐ๋ค์ AVL ํธ๋ฆฌ์ ๊ท ํ์ ์ ์งํ๋ ๋ฐ ํต์ฌ์ ์ธ ์ญํ ์ ํฉ๋๋ค. ํ์ ์ฐ์ฐ์ ํตํด AVL ํธ๋ฆฌ๋ ๋ชจ๋ ๋
ธ๋์์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด ์ฐจ๊ฐ ๋ง์์ผ 1์ด ๋๋๋ก ๊ท ํ์ ์ ์งํฉ๋๋ค.
ํ๋ง๋๋ก,
ํ์ ์ฐ์ฐ์ AVL ํธ๋ฆฌ์์ ๊ท ํ์ด ๊นจ์ง ๊ฒฝ์ฐ ์ด๋ฅผ ๋ณต์ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํธ๋ฆฌ ์ฌ๊ตฌ์กฐํ ๋ฐฉ๋ฒ์ ๋๋ค
'CS - Roadmap.sh > 1. Data structures' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Data structures (with python) - 8.Tree - 8.6 Unbalanced Tree (0) | 2024.01.13 |
---|---|
Data structures (with python) - 8.Tree - 8.4 Complete Binary Tree (1) | 2024.01.11 |
Data structures (with python) - 8.Tree - 8.3 Full Binary Tree (1) | 2024.01.10 |
Data structures (with python) - 8.Tree - 8.2 Binary Search Tree (0) | 2024.01.09 |
Data structures (with python) - 8.Tree - 8.1 Binary Tree (0) | 2024.01.09 |