๋ฐ์ํ
๐ ์ด์ง ํธ๋ฆฌ (binary Search tree) - ์ญ์
๋ ธ๋ ์ญ์
๋ ธ๋๋ฅผ ํ๋ ์ญ์ ํด๋ณด์. ๋ ธ๋๋ฅผ ์ญ์ ํ๋ ๊ฒฝ์ฐ๋ 3๊ฐ์ง๊ฐ ์๋ค. ์์ ๋ ธ๋๊ฐ ์์ ๊ฒฝ์ฐ, ์์ ๋ ธ๋๊ฐ ํ๋์ธ ๊ฒฝ์ฐ, ์์๋ ธ๋๊ฐ ๋์ธ๊ฒฝ์ฐ๋ก ๋๋ ์ ์๋ค.
๐ต ์์ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ
- ์์ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ๋ ๊ทธ๋ฅ ์ญ์ ํ๋ฉด ๋๋ค.
๐ต ์์ ๋ ธ๋๊ฐ ํ๋์ธ ๊ฒฝ์ฐ
- ์์ ๋ ธ๋๊ฐ ํ๋์ธ ๊ฒฝ์ฐ๋ ์ญ์ ํ ๋ ธ๋๋ฅผ ์ญ์ ํ๊ณ , ๊ทธ ์์ ๋ ธ๋๋ฅผ ํ ์๋ฒ์ง ๋ ธ๋์ ๋ถ์ด๋ฉด ๋๋ค.
๐ต ์์ ๋ ธ๋๊ฐ ๋์ธ ๊ฒฝ์ฐ
- ์์ ๋ ธ๋๊ฐ ๋์ธ ๊ฒฝ์ฐ๋ ์ญ์ ํ ๋ ธ๋๋ฅผ ์ญ์ ํ๊ณ , ๊ทธ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์ผ์ชฝ ์์์ ๊ฐ์ ธ์์ ์ญ์ ํ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋์ ๋ถ์ฌ์ค๋ค.
๐ต ์ ์ฒด ์ฝ๋
# ๋
ธ๋ ๋ง๋ค๊ธฐ
# A(val)
# / \
# B(left) C(right)
class Node:
def __init__(self, item):
self.val = item
self.left = None
self.right = None
# ์ด์งํธ๋ฆฌ ๋ง๋ค๊ธฐ
class BinaryTree:
# ์ด๊ธฐ๊ฐ head๋ None
def __init__(self):
self.head = Node(None)
self.preorder_list = []
self.inorder_list = []
self.postorder_list = []
# ๊ฐ ์ถ๊ฐํ๊ธฐ head๊ฐ ์์ ๊ฒฝ์ฐ
def add(self, item):
if self.head.val is None:
self.head.val = item
# head๊ฐ ์์ผ๋ฉด ์ผ์ชฝ๋ฐฐ์น or ์ค๋ฅธ์ชฝ๋ฐฐ์น
else:
self.__add_node(self.head, item)
# head๊ฐ ์๋ ๊ฒฝ์ฐ
def __add_node(self, cur, item):
print('๋ถ๋ชจ:', cur.val, '์์:', item)
# head ๊ฐ์ด ํฌ๋ฉด ์ผ์ชฝ์ผ๋ก
if cur.val >= item:
if cur.left is not None:
self.__add_node(cur.left, item)
else:
cur.left = Node(item)
# head ๊ฐ์ด ์์ผ๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก
else:
if cur.right is not None:
self.__add_node(cur.right, item)
else:
cur.right = Node(item)
# ์ฐพ๊ธฐ!!
def search(self, item):
if self.head.val is None:
return False
else:
return self.__search_node(self.head, item)
def __search_node(self, cur, item):
print(cur.val, item)
if cur.val == item:
return True
else:
if cur.val >= item:
if cur.left is not None:
return self.__search_node(cur.left, item)
else:
return False
else:
if cur.right is not None:
return self.__search_node(cur.right, item)
else:
return False
# ์ง์ฐ๊ธฐ!!
def remove(self, item):
if self.head.val == item:
# ์์์ด ์์ ๋ - ๊ทธ๋ฅ ์ง์ด๋ค
if self.head.left == None and self.head.right == None:
self.head.val = None
# ์์์ด ํ๋์์ ๋ - ๋ถ๋ชจ๋ฅผ ์ง์ฐ๊ณ ์์์ ํ ์๋ฒ์งํํ
๋ถ์ธ๋ค.
elif self.head.left == None and self.head.right != None:
self.head = self.head.right
elif self.head.left != None and self.head.right == None:
self.head = self.head.left
# ์์์ด ๋ ์์ ๋ - ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์ผ์ชฝ ์์์ผ๋ก ๋ฐ๊ฟ์ค๋ค.
else:
self.head.val = self.__remove_right_and_most_left(self.head.right)
else:
if self.head.val > item:
self.__remove(self.head, self.head.left, item)
else:
# print(self.head.val, self.head.right.val, item)
self.__remove(self.head, self.head.right, item)
def __remove(self, parent, cur, item):
print(parent.val, cur.val, item)
if cur is None:
print('No item', item)
if cur.val == item:
# ์์์ด ์์ ๋
if cur.left == None and cur.right == None:
print('์ฌ๊ธฐ์ค๋ค')
if parent.left == cur:
parent.left = None
else:
parent.right = None
# ์์์ด ํ๋ ์์ ๋ - ๋ถ๋ชจ๋ฅผ ์ง์ฐ๊ณ ์์์ ํ ์๋ฒ์งํํ
๋ถ์ธ๋ค.
elif cur.left == None and cur.right != None:
if parent.left == cur:
parent.left = cur.right
else:
parent.right = cur.right
elif cur.left != None and cur.right == None:
if parent.left == cur:
parent.left = cur.left
else:
parent.right = cur.left
# ์์์ด ๋ ์์ ๋ - ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์ผ์ชฝ ์์์ผ๋ก ๋ฐ๊ฟ์ค๋ค.
if cur.left != None and cur.right != None:
cur.val = self.__remove_right_and_most_left(cur.right).val
self.__removeitem(cur, cur.right, cur.val)
else:
if cur.val > item:
self.__remove(cur, cur.left, item)
else:
self.__remove(cur, cur.right, item)
# ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์ผ์ชฝ ์์ ์ฐพ๊ธฐ
def __remove_right_and_most_left(self, cur):
if cur.left == None:
return cur
else:
return self.__remove_right_and_most_left(cur.left)
# ์์์ด ๋์ผ ๋ ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์ผ์ชฝ ์์์ ์ฎ๊ธฐ๊ณ ๊ทธ ์์์ ์ง์ฐ๊ธฐ
def __removeitem(self, parent, cur, item):
if cur.val == item:
if parent.left == cur:
parent.left = None
else:
parent.right = None
else:
if cur.val > item:
self.__removeitem(cur, cur.left, item)
else:
self.__removeitem(cur, cur.right, item)
# ์ํ Traverse
# ์ ์์ํ preorder 1. ๋ฃจํธ ๋ฐฉ๋ฌธ, 2. ์ผ์ชฝ ์๋ธํธ๋ฆฌ, 3. ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ
# ์์ฑ๋์ด ์๋ ํธ๋ฆฌ๋ฅผ ๋ค๋ฅธ ์๋ฒ์ ๋ฆฌ์คํธ ํํ๋ก ๋ณด๋ด์ ๊ทธ ์๋ฒ์์ ๋ค์ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ ๋ ์ฌ์ฉ
def preorder_traverse(self):
self.preorder_list = []
if self.head is not None:
self.__preorder(self.head)
def __preorder(self, cur):
self.preorder_list.append(cur.val)
# print(cur.val)
if cur.left is not None:
self.__preorder(cur.left)
if cur.right is not None:
self.__preorder(cur.right)
# ์ ์์ํ inorder 1. ์ผ์ชฝ 2. ๋ฃจํธ 3. ์ค๋ฅธ์ชฝ
# ์ค๋ฆ์ฐจ์ ์ ๋ ฌํ ๋ | n์ ์๊ฐ๋ณต์ก๋๋ก ์ ๋ ฌ๊ฐ๋ฅ
def inorder_traverse(self):
self.inorder_list = []
if self.head is not None:
self.__inorder(self.head)
def __inorder(self, cur):
if cur.left is not None:
self.__inorder(cur.left)
self.inorder_list.append(cur.val)
# print(cur.val)
if cur.right is not None:
self.__inorder(cur.right)
# ํ์์ํ postorder 1. ์ผ์ชฝ, 3. ์ค๋ฅธ์ชฝ, 3. ๋ฃจํธ
#
def postorder_traverse(self):
self.postorder_list = []
if self.head is not None:
self.__postorder(self.head)
def __postorder(self, cur):
if cur.left is not None:
self.__postorder(cur.left)
if cur.right is not None:
self.__postorder(cur.right)
self.postorder_list.append(cur.val)
# print(cur.val)
lst = [50, 30, 24, 5, 28, 45, 98, 52, 60]
bt = BinaryTree()
for num in lst:
bt.add(num)
print(bt.search(60))
# ์ ์ฐ
bt.preorder_traverse()
print(bt.preorder_list)
# ์ค์
bt.inorder_traverse()
print(bt.inorder_list)
# ํ์
bt.postorder_traverse()
print(bt.postorder_list)
bt.remove(24)
print(bt.search(60))
# ์ ์ฐ
bt.preorder_traverse()
print(bt.preorder_list)
# ์ค์
bt.inorder_traverse()
print(bt.inorder_list)
# ํ์
bt.postorder_traverse()
print(bt.postorder_list)
# ์ถ์ฒ: https://www.youtube.com/watch?v=0CqDdXOr6Kk
๋ฐ์ํ
'CS > Data Structure' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ(queue) (0) | 2020.11.07 |
---|---|
์คํ(Stack) (0) | 2020.11.04 |
[python] ์ด์ง ํ์ ํธ๋ฆฌ (binary Search tree) - 3. ์ํ (0) | 2020.09.04 |
[python] ์ด์ง ํ์ ํธ๋ฆฌ (binary Search tree) - 2. ํ์ (0) | 2020.09.03 |
[python] ์ด์ง ํ์ ํธ๋ฆฌ (binary Search tree) - 1. ํด๋์ค ์ ์, ์ด๊ธฐํ, ๋ ธ๋ ์ถ๊ฐ (0) | 2020.09.02 |