DOing
[์๋ฃ๊ตฌ์กฐ] ์ด์ง ํ์ ํธ๋ฆฌ with Python ๋ณธ๋ฌธ
๐ก ์ด์ง ํ์ ํธ๋ฆฌ(Binary Search Tree)
: ์ด์งํธ๋ฆฌ์ ๋ค์๊ณผ ๊ฐ์ ์ถ๊ฐ์ ์ธ ์กฐ๊ฑด์ด ์๋ ํธ๋ฆฌ
1) ๋ชจ๋ ๋ ธ๋๋ ์ผ์ชฝ ๊ฐ์ง์ ํฌํจ๋๋ ์ด๋ค ์ซ์๋ณด๋ค๋ ํฐ๊ฐ์ ๊ฐ์ง๋ค.
2) ๋ชจ๋ ๋ ธ๋๋ ์ค๋ฅธ์ชฝ ๊ฐ์ง์ ํฌํจ๋๋ ์ด๋ค ์ซ์๋ณด๋ค๋ ์์๊ฐ์ ๊ฐ์ง๋ค.
ํด๋น ๊ทธ๋ฆผ์์ ๋ณผ ๋ 14๋ฅผ ์์๋ก ๋ค์ด๋ณด์.
1) 14๋ ์ผ์ชฝ๊ฐ์ง์ ํฌํจ๋๋ 11๋ณด๋ค ํฐ๊ฐ์ ๊ฐ์ง๋ค.
2) 14๋ ์ค๋ฅธ์ชฝ๊ฐ์ง์ ํฌํจ๋๋ 15,18,19๋ณด๋ค ์์๊ฐ์ ๊ฐ์ง๋ค.
๐ก ์ด์ง ํ์ ํธ๋ฆฌ ์ฝ์ , ํ์ ๋์๊ณผ์
[ ํ์๊ณผ์ ]
1. ์ฐพ๋ ์ซ์๊ฐ ํ์ฌ ๋ ธ๋ ๊ฐ๊ณผ ๊ฐ๋ค๋ฉด ํ์ ์ฑ๊ณต!
2. ์ฐพ๋ ์ซ์๊ฐ ํ์ฌ ๋ ธ๋ ๊ฐ๋ณด๋ค ์๋ค๋ฉด ์ผ์ชฝ์ผ๋ก ๊ฐ๋ค.
3. ์ฐพ๋ ์ซ์๊ฐ ํ์ฌ ๋ ธ๋ ๊ฐ๋ณด๋ค ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ๋ค.
[ ์ฝ์ ๊ณผ์ ]
1. ์ฝ์ ํ ์ซ์๊ฐ ํ์ฌ ๋ ธ๋ ๊ฐ๋ณด๋ค ์๋ค๋ฉด ์ผ์ชฝ์ผ๋ก ๊ฐ๋ค.
2. ์ฝ์ ํ ์ซ์๊ฐ ํ์ฌ ๋ ธ๋ ๊ฐ๋ณด๋ค ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ๋ค.
3. ์์๋ ธ๋๊ฐ ์์ ๋๊น์ง 1~2๊ณผ์ ์ ๋ฐ๋ณตํ๊ณ ์์๋ ธ๋๊ฐ ์์ ๋ ๋ง๋ค์ด์ ์ฐ๊ฒฐ์์ผ์ค๋ค.
๐ก ์ด์ง ํ์ ํธ๋ฆฌ ์ฝ์ , ํ์ ์ฝ๋
class Node:
def __init__(self, value):
# double linked list
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
# ์ด์ง ํ์ ํธ๋ฆฌ ์ถ๋ ฅ
def search(self, value):
self.current_node = self.head
while self.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 # ๋ค ์ฐพ์๋ดค๋๋ฐ ์๋ค.
# ์คํ
head = Node(1)
BST = NodeMgmt(head)
BST.insert(2)
BST.insert(3)
print(BST.search(2))
print(BST.search(5))
๐ก ์ด์ง ํ์ ํธ๋ฆฌ์ ์ญ์ ๋์
์ด์ง ํ์ ํธ๋ฆฌ์ ์ญ์ ๋ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๊ฒฝ์ฐ๋ฅผ ๋๋ ์ ์๊ฐํด๋ณด์.
1) Leaf Node๋ฅผ ์ญ์
: parent node๊ฐ ์ญ์ ํ ๋ ธ๋๋ฅผ ๊ฐ๋ฅดํค์ง ์๋๋ก ํ๋ค.
2) Child Node๊ฐ ํ๊ฐ์ธ Node ์ญ์
: ์ญ์ ํ ๋ ธ๋์ Parent Node๊ฐ ์ญ์ ํ Node์ child Node๋ฅผ ๊ฐ๋ฅดํค๋๋ก ํ๋ค.
3) Child Node๊ฐ ๋๊ฐ์ธ Node ์ญ์ (์ค์!)
: ์ญ์ ํ Node์ ์ค๋ฅธ์กฑ ์์ ์ค, ๊ฐ์ฅ ์์๊ฐ์ Parent Node๊ฐ ๊ฐ๋ฆฌํค๋๋กํ๋ค.
: ๋๋ ์ญ์ ํ ๋ ธ๋์ ์ผ์ชฝ ์์ ์ค, ๊ฐ์ฅ ํฐ๊ฐ์ Parent Node๊ฐ ๊ฐ๋ฆฌํค๋๋กํ๋ค.
๊ธ๋ก ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
1. ์ญ์ ํ Node์ ์ค๋ฅธ์ชฝ์์ ์ ํ
2. ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์ผ์ชฝ์ ์๋ Node ์ ํ
3. ํด๋น Node๋ฅผ ์ญ์ ํ Node์ Parent Node์ ์ผ์ชฝ ๋ธ๋์น๊ฐ ๊ฐ๋ฅดํค๊ฒ ํจ.
4. ํด๋น Node์ ์ผ์ชฝ ๋ธ๋์น๊ฐ ์ญ์ ํ Node์ ์ผ์ชฝ child Node๋ฅผ ๊ฐ๋ฅดํค๊ฒ ํจ
5. ํด๋น Node์ ์ค๋ฅธ์ชฝ branch๊ฐ ์ญ์ ํ Node์ ์ค๋ฅธ์ชฝ child Node๋ฅผ ๊ฐ๋ฅดํค๊ฒ ํจ
6. ๋ง์ฝ ํด๋น Node๊ฐ ์ค๋ฅธ์ชฝ child node๋ฅผ ๊ฐ์ง๊ณ ์์์ ๊ฒฝ์ฐ,
ํด๋น Node์ ๋ณธ๋ Parent Node์ ์ผ์ชฝ ๋ธ๋์น๊ฐ ํด๋น Node์ ์ค๋ฅธ์ชฝ child Node๋ฅผ ๊ฐ๋ฅดํค๊ฒํจ
์ด๊ฑธ ์ฝ๋๋ก ์ฎ๊ธฐ๋ฉด๋๋ค...^^
๐ก ์ด์ง ํ์ ํธ๋ฆฌ์ ์ญ์ ์ฝ๋
์๊น ์จ๋ฃ์ NodeMgmt ํด๋์ค์ ๋ค์ด๊ฐ๋ ํจ์๋ผ๋ ๊ฒ์ ๊ธฐ์ตํด๋ผ.
๋ค ๋ฃ์ผ๋ ค๋ฉด ๋๋ฌด ๊ธธ์ด์ง๋๊น!
def delete(self, value):
# ์ญ์ ํ ๋
ธ๋ ํ์
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.curent_node = self.current_node.left # ๋น๊ต๋์ ๋ณ๊ฒฝ
else:
self.parent = self.current_node
self.current_node = self.current_node.right # ๋น๊ต๋์ ๋ณ๊ฒฝ
if searched == False: # ๊ทธ๋ฐ ๊ฐ์ ๊ฐ์ง ๋
ธ๋๊ฐ ์๋ค = ์ญ์ ํ ๋
ธ๋๊ฐ ์๋ค
return False
## ํด๋น๋
ธ๋๋ฅผ ์ฐพ์๋ค. ์ด์ ์ญ์ ๋ฅผ ํ์!
1) Leaf Node๋ฅผ ์ญ์
: parent node๊ฐ ์ญ์ ํ ๋ ธ๋๋ฅผ ๊ฐ๋ฅดํค์ง ์๋๋ก ํ๋ค.
# case1
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
2) Child Node๊ฐ ํ๊ฐ์ธ Node ์ญ์
: ์ญ์ ํ ๋ ธ๋์ Parent Node๊ฐ ์ญ์ ํ Node์ child Node๋ฅผ ๊ฐ๋ฅดํค๋๋ก ํ๋ค.
child ๋ ธ๋๋ฅผ ์ค๋ฅธ์ชฝ์ ๊ฐ์ง๊ณ ์๋, ์ผ์ชฝ์ ๊ฐ์ง๊ณ ์๋์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฝ๋๋ฅผ ๊ฐ์ง๋ค.
# case2
# ์ผ์ชฝ ๋
ธ๋๋ง ๊ฐ์ง๊ณ ์๋ค.
elif self.current_node.left != None and self.current_node.right == None:
# ์ญ์ ํ ๋
ธ๋๊ฐ parent์ ์ค๋ฅธ์ชฝ์ ์๋ ์ผ์ชฝ์ ์๋
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.parent.left = self.current_node.right
else:
self.parent.right = self.current_node.right
3) Child Node๊ฐ ๋๊ฐ์ธ Node ์ญ์
3-1. ์ญ์ ํ ๋ ธ๋๊ฐ parent node ์ผ์ชฝ์ ์๋ค.
3-1-1. ์ญ์ ํ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์์ค, ๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ์ง node์ chlid node๊ฐ ์์๋
3-1-2. ์ญ์ ํ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์์ค, ๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ์ง node์ ์ค๋ฅธ์ชฝ์ chlid node๊ฐ ์์๋
: ์ค๋ฅธ์ชฝ์ chlid node๊ฐ ์์ ์ ์๋ค. ์ผ์ชฝ์ ์์์ผ๋ฉด ๊ฑ๊ฐ ์ฌ๋ผ๊ฐ๊ฒ ์ง?
# case3 : ์ญ์ ํ ๋
ธ๋๊ฐ ๋๊ฐ์ ์์์ ๊ฐ์ง๋ค
if self.current_node.left != None and self.current_node.right != None:
# case3-1 : ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ ๋
ธ๋์ ์ผ์ชฝ์ ์๋ค
if value < self.parent.value:
self.change_node = self.current_node.right
self.change_node_parent = self.current_node.right
# ๊ฐ์ฅ ์์๊ฐ์ ๋ฌด์กฐ๊ฑด left์ ์๋ค = ์ผ๋จ left ๋๊น์ง ๊ฐ๊ฒ
while self.change_node.left != None:
self.change_node_parent = self.change_node
self.change_node = self.change_node.left
# 3-1-2
if self.change_node.right != None:
self.change_node_parent.left = self.change_node.right
else: # 3-1-1
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
3-2. ์ญ์ ํ ๋ ธ๋๊ฐ parent node์ ์ค๋ฅธ์ชฝ์ ์๋ค.
3-2-1. ์ญ์ ํ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์์ค, ๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ์ง node์ chlid node๊ฐ ์์๋
3-2-2. ์ญ์ ํ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์์ค, ๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ์ง node์ ์ค๋ฅธ์ชฝ์ chlid node๊ฐ ์์๋
: ์ค๋ฅธ์ชฝ์ chlid node๊ฐ ์์ ์ ์๋ค. ์ผ์ชฝ์ ์์์ผ๋ฉด ๊ฑ๊ฐ ์ฌ๋ผ๊ฐ๊ฒ ์ง?
# case3-2 : ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ ๋
ธ๋์ ์ค๋ฅธ์ชฝ์ ์๋ค
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.chage_node = self.change_node.left # ๋น๊ต ๋์ ๋ณ๊ฒฝ
# 3-2-2
if self.chage_node.right != None:
self.change_node_parent.left = self.change_node.right
else: # 3-2-1
self.change_node_parent.left = None
# ์๋ก ์ฎ๊ธด๋ค.
self.parent.right = self.change_node
self.change_node.left = self.current_node.left
self.chage_node.right = self.current_node.right
์ ์ฒด ์ฝ๋ ๋ณด๊ธฐ
class Node:
def __init__(self, value):
# double linked list
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
# ์ด์ง ํ์ ํธ๋ฆฌ ์ถ๋ ฅ
def search(self, value):
self.current_node = self.head
while self.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 # ๋ค ์ฐพ์๋ดค๋๋ฐ ์๋ค.
def delete(self, value):
# ์ญ์ ํ ๋
ธ๋ ํ์
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.curent_node = self.current_node.left # ๋น๊ต๋์ ๋ณ๊ฒฝ
else:
self.parent = self.current_node
self.current_node = self.current_node.right # ๋น๊ต๋์ ๋ณ๊ฒฝ
if searched == False: # ๊ทธ๋ฐ ๊ฐ์ ๊ฐ์ง ๋
ธ๋๊ฐ ์๋ค = ์ญ์ ํ ๋
ธ๋๊ฐ ์๋ค
return False
## ํด๋น๋
ธ๋๋ฅผ ์ฐพ์๋ค. ์ด์ ์ญ์ ๋ฅผ ํ์!
# case1
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
# case2
# ์ผ์ชฝ ๋
ธ๋๋ง ๊ฐ์ง๊ณ ์๋ค.
elif self.current_node.left != None and self.current_node.right == None:
# ์ญ์ ํ ๋
ธ๋๊ฐ parent์ ์ค๋ฅธ์ชฝ์ ์๋ ์ผ์ชฝ์ ์๋
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.parent.left = self.current_node.right
else:
self.parent.right = self.current_node.right
# case3 : ์ญ์ ํ ๋
ธ๋๊ฐ ๋๊ฐ์ ์์์ ๊ฐ์ง๋ค
if self.current_node.left != None and self.current_node.right != None:
# case3-1 : ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ ๋
ธ๋์ ์ผ์ชฝ์ ์๋ค
if value < self.parent.value:
self.change_node = self.current_node.right
self.change_node_parent = self.current_node.right
# ๊ฐ์ฅ ์์๊ฐ์ ๋ฌด์กฐ๊ฑด left์ ์๋ค = ์ผ๋จ left ๋๊น์ง ๊ฐ๊ฒ
while self.change_node.left != None:
self.change_node_parent = self.change_node
self.change_node = self.change_node.left
# 3-1-2
if self.change_node.right != None:
self.change_node_parent.left = self.change_node.right
else: # 3-1-1
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
# case3-2 : ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ ๋
ธ๋์ ์ค๋ฅธ์ชฝ์ ์๋ค
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.chage_node = self.change_node.left # ๋น๊ต ๋์ ๋ณ๊ฒฝ
# 3-2-2
if self.chage_node.right != None:
self.change_node_parent.left = self.change_node.right
else: # 3-2-1
self.change_node_parent.left = None
# ์๋ก ์ฎ๊ธด๋ค.
self.parent.right = self.change_node
self.change_node.left = self.current_node.left
self.chage_node.right = self.current_node.right
# 1๋ถํฐ 999 ์ซ์ ์ค์์ ์์๋ก 100๊ฐ ์ถ์ถํ์ฌ ์ด์ง ํธ๋ฆฌ์ ์
๋ ฅ/๊ฒ์/์ญ์
import random
# 1~999์ค 100๊ฐ์ ์ซ์ ๋๋ค ์ ํ
bst_nums = set() # 100๊ฐ๋ฅผ ๋๋ค์ ํํ๋ค๋ณด๋ฉด ์ค๋ณต์ด ์์ ์ ์๋๋ฐ ์งํฉ(set)์ผ๋ก ์ด๋ฅผ ๋ฐฉ์ง
while len(bst_nums) != 100:
bst_nums.add(random.randint(0, 999)) # ์ค๋ณต์ด๋ผ๋ฉด ์์ ๋ค์ด๊ฐ์ง ์์. ๊ทธ๋์ ๋ฐ๋ณต๋ฌธ์ 100๋ฒ ์ด์ ์คํ๋ ๊ฐ๋ฅ์ฑ์ด ๋์
#print(bst_nums)
# ์ ํ๋ 100๊ฐ์ ์ซ์๋ฅผ ์ด์ง ํ์ํธ๋ฆฌ์ ์
๋ ฅ, ๋ฃจํธ๋
ธํธ๋ 500์ผ๋ก ์์๋ก ์ง์
# 1์ด๋ 999์ด๋ฌ๋ฉด ํ์ชฝ์ ์น์ฐ์น ํธ๋ฆฌ๊ฐ ๋ ๊ฒ์ด๋ค. ์ฃผ์ํ์
head = Node(500)
binary_tree = NodeMgmt(head)
for num in bst_nums:
binary_tree.insert(num)
# ์
๋ ฅํ 100๊ฐ์ ์ซ์ ๊ฒ์ (๊ฒ์ ๊ธฐ๋ฅ ํ์ธ)
for num in bst_nums:
if binary_tree.search(num) == False:
print("search failed", num) # ์ด๊ฒ ์ฌ์ค ๋์ค๋ฉด ์ฝ๋ ์๋ชป์ง ๊ฒ์
# ์
๋ ฅํ 100๊ฐ์ ์ซ์ ์ค 10๊ฐ์ ์ซ์๋ฅผ ๋๋ค ์ ํ
delete_nums = set()
bst_nums = list(bst_nums) # ์ธ๋ฑ์ค๋ก ์ ๊ทผํ๊ธฐ ์ํด listํ์
์ผ๋ก ๋ณํ์ํจ๋ค.
while len(delete_nums) != 10:
delete_nums.add(bst_nums[random.randint(0, 99)])
# ์ ํํ 10๊ฐ์ ์ซ์๋ฅผ ์ญ์ (์ญ์ ๊ธฐ๋ฅํ์ธ)
for del_num in delete_nums:
if binary_tree.delete(del_num) == False:
print('delete failed', del_num) # ์ด๊ฒ ์ฌ์ค ๋์ค๋ฉด ์ฝ๋ ์๋ชป์ง ๊ฒ์
ํ ์คํธ ์ฝ๋
ํ ์คํธ ์ฝ๋๋ฅผ ๋๋ ธ์๋ ์๋ฌด๊ฒ๋ ๋์ค์ง ์๋๋ค๋ฉด ์ ์ง ๊ฒ์ด๋ค.
# 1๋ถํฐ 999 ์ซ์ ์ค์์ ์์๋ก 100๊ฐ ์ถ์ถํ์ฌ ์ด์ง ํธ๋ฆฌ์ ์
๋ ฅ/๊ฒ์/์ญ์
import random
# 1~999์ค 100๊ฐ์ ์ซ์ ๋๋ค ์ ํ
bst_nums = set() # 100๊ฐ๋ฅผ ๋๋ค์ ํํ๋ค๋ณด๋ฉด ์ค๋ณต์ด ์์ ์ ์๋๋ฐ ์งํฉ(set)์ผ๋ก ์ด๋ฅผ ๋ฐฉ์ง
while len(bst_nums) != 100:
bst_nums.add(random.randint(0, 999)) # ์ค๋ณต์ด๋ผ๋ฉด ์์ ๋ค์ด๊ฐ์ง ์์. ๊ทธ๋์ ๋ฐ๋ณต๋ฌธ์ 100๋ฒ ์ด์ ์คํ๋ ๊ฐ๋ฅ์ฑ์ด ๋์
#print(bst_nums)
# ์ ํ๋ 100๊ฐ์ ์ซ์๋ฅผ ์ด์ง ํ์ํธ๋ฆฌ์ ์
๋ ฅ, ๋ฃจํธ๋
ธํธ๋ 500์ผ๋ก ์์๋ก ์ง์
# 1์ด๋ 999์ด๋ฌ๋ฉด ํ์ชฝ์ ์น์ฐ์น ํธ๋ฆฌ๊ฐ ๋ ๊ฒ์ด๋ค. ์ฃผ์ํ์
head = Node(500)
binary_tree = NodeMgmt(head)
for num in bst_nums:
binary_tree.insert(num)
# ์
๋ ฅํ 100๊ฐ์ ์ซ์ ๊ฒ์ (๊ฒ์ ๊ธฐ๋ฅ ํ์ธ)
for num in bst_nums:
if binary_tree.search(num) == False:
print("search failed", num) # ์ด๊ฒ ์ฌ์ค ๋์ค๋ฉด ์ฝ๋ ์๋ชป์ง ๊ฒ์
# ์
๋ ฅํ 100๊ฐ์ ์ซ์ ์ค 10๊ฐ์ ์ซ์๋ฅผ ๋๋ค ์ ํ
delete_nums = set()
bst_nums = list(bst_nums) # ์ธ๋ฑ์ค๋ก ์ ๊ทผํ๊ธฐ ์ํด listํ์
์ผ๋ก ๋ณํ์ํจ๋ค.
while len(delete_nums) != 10:
delete_nums.add(bst_nums[random.randint(0, 99)])
# ์ ํํ 10๊ฐ์ ์ซ์๋ฅผ ์ญ์ (์ญ์ ๊ธฐ๋ฅํ์ธ)
for del_num in delete_nums:
if binary_tree.delete(del_num) == False:
print('delete failed', del_num) # ์ด๊ฒ ์ฌ์ค ๋์ค๋ฉด ์ฝ๋ ์๋ชป์ง ๊ฒ์
๐ก ์ด์ง ํ์ ํธ๋ฆฌ์ ์๊ฐ ๋ณต์ก๋์ ๋จ์
[ ์๊ฐ ๋ณต์ก๋ ]
: ๋ ธ๋๊ฐ n๊ฐ ์ผ๋ ํธ๋ฆฌ์ ๋์ด h = logn์ด๋ค.
: ์ฆ, ์ด์ง ํ์ํธ๋ฆฌ์ ์๊ฐ๋ณต์ก๋๋ O(logn)์ผ๋ก ๋ฆฌ์คํธ์์ ํ์ํ ์์๋ O(n)์ด ๊ฑธ๋ฆฌ๋ ๊ฒ์ ๋นํด ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๊ฐ๋ฅํ๋ค.
[ ๋จ์ ]
: O(logn)์ ํธ๋ฆฌ๊ฐ ๊ท ํ์กํ์์ ๋์ ํ๊ท ์๊ฐ๋ณต์ก๋์ด๋ค.
: ์์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด root node๋ฅผ ์๋ชป์ก์์ ํธ๋ฆฌ๊ฐ ๋ถ๊ท ํ์ด ๋์ด ์ต์ ์ ๊ฒฝ์ฐ, linked list์ ๋์ผํ ์ฑ๋ฅ์ ๋ณด์ผ ์ ์๋ค. ๊ทธ๋์ ๊ท ํ์กํ ํธ๋ฆฌ๋ฅผ ์ก๋ ๊ฒ์ด ์ค์ํ๋ฐ, ๊น๊ฒ ๋ค์ด๊ฐ๋ฉด ์ด๋ฐ ์๊ณ ๋ฆฌ์ฆ๋ ์กด์ฌํ๋ค.
์ถ์ฒ
PENJEE.COM'S BLOG : ์ด์งํ์ํธ๋ฆฌ
ํจ์คํธ ์บ ํผ์ค ์๊ณ ๋ฆฌ์ฆ ์ฌ์ธ์ ๊ฐ์
'์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฃ๊ตฌ์กฐ] ์คํ, ํ, ๋ฐํ (0) | 2021.06.22 |
---|---|
[์๋ฃ๊ตฌ์กฐ] ๊ทธ๋ํ (0) | 2021.06.15 |
[์๊ณ ๋ฆฌ์ฆ] Disjoint Sets(์๋ก์ ์งํฉ) (0) | 2021.05.31 |
[์๊ณ ๋ฆฌ์ฆ] ํ๋ก์ด๋ ์์ with Python (0) | 2021.05.23 |
[์๊ณ ๋ฆฌ์ฆ] ๋ค์ต์คํธ๋ผ ์ต๋จ๊ฒฝ๋ก with Python (0) | 2021.05.23 |