CS/Data Structure

[python] ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ (binary Search tree) - 3. ์ˆœํšŒ

deo2kim 2020. 9. 4. 20:09
๋ฐ˜์‘ํ˜•

๐Ÿ“— ์ด์ง„ ํŠธ๋ฆฌ (binary Search tree) - ์ˆœํšŒ

ํŠธ๋ฆฌ ์ˆœํšŒ

ํŠธ๋ฆฌ ์ˆœํšŒ๋Š” ํŠธ๋ฆฌ์— ์ €์žฅ๋œ ๊ฐ’์„ ๋ชจ๋‘ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์ˆœํšŒ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ๊ฐ’์„ ํ™•์ธํ•˜๋Š” ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๋‹ค.์ˆœํšŒ์˜ ์ข…๋ฅ˜๋กœ๋Š” ์ „์œ„ ์ˆœํšŒ (preorder traversal), ์ค‘์œ„ ์ˆœํšŒ(inorder traversal), ํ›„์œ„ ์ˆœํšŒ(postorder traversal)์ด ์žˆ๋‹ค.

 

๐Ÿ”ต ์ „์œ„ ์ˆœํšŒ (preorder traversal)

๐Ÿ’จ ์™„์„ฑ๋˜์–ด ์žˆ๋Š” ํŠธ๋ฆฌ๋ฅผ ๋‹ค๋ฅธ ์„œ๋ฒ„์— ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ณด๋‚ด์„œ ๊ทธ ์„œ๋ฒ„์—์„œ ๋‹ค์‹œ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ

 ๋…ธ๋“œ > ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ˆœ์œผ๋กœ ์ˆœํšŒํ•œ๋‹ค. ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๋…ธ๋“œ ๋ฐฉ๋ฌธ
  • ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋ฐฉ๋ฌธ
  • ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋ฐฉ๋ฌธ

์ „์œ„ ์ˆœํšŒ

์ „์œ„ ์ˆœํšŒ ๊ฒฐ๊ณผ:  F, B, A, D, C, E, G, I, H 

    def preorder_traverse(self):
        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 traversal)

๐Ÿ’จ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•  ๋•Œ, O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ์ •๋ ฌ ๊ฐ€๋Šฅ

์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ๋…ธ๋“œ > ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ˆœ์œผ๋กœ ์ˆœํšŒํ•œ๋‹ค. ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋ฐฉ๋ฌธ
  • ๋…ธ๋“œ ๋ฐฉ๋ฌธ
  • ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋ฐฉ๋ฌธ

์ค‘์œ„ ์ˆœํšŒ

์ค‘์œ„ ์ˆœํšŒ ๊ฒฐ๊ณผ:  A, B, C, D, E, F, G, H, I 

    def inorder_traverse(self):
        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 traversal)

์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ๋…ธ๋“œ ์ˆœ์œผ๋กœ ์ˆœํšŒํ•œ๋‹ค. ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋ฐฉ๋ฌธ
  • ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋ฐฉ๋ฌธ
  • ๋…ธ๋“œ ๋ฐฉ๋ฌธ

 

ํ›„์œ„ ์ˆœํšŒ ๊ฒฐ๊ณผ:  A, C, E, D, B, H, I, G, F 

    def postorder_traverse(self):
        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)
        
        

๐Ÿ”ต ์ „์ฒด ์ฝ”๋“œ

# ๋…ธ๋“œ ๋งŒ๋“ค๊ธฐ
#         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 preorder_traverse(self):
        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)

    # ์ค‘์œ„์ˆœํšŒ
    def inorder_traverse(self):
        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)

    # ํ›„์œ„์ˆœํšŒ
    def postorder_traverse(self):
        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)

# ์ถœ์ฒ˜: https://www.youtube.com/watch?v=0CqDdXOr6Kk

 

๋ฐ˜์‘ํ˜•