์ž๋ฃŒ๊ตฌ์กฐ ๐Ÿ—„ Tree ๐ŸŒณ

yeeun leeยท2020๋…„ 4์›” 28์ผ
1

1. Tree

Tree๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฑฐ๊พธ๋กœ๋œ ๋‚˜๋ฌด ํ˜•ํƒœ๋กœ ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ๋‹ค. ์—ฌ๋Ÿฌ ์œ ํ˜•์ด ์žˆ์ง€๋งŒ ๊ทธ ์ค‘ ๊ฐ€์žฅ ๊ธฐ๋ณธ์€ binary tree(์ด์ง„ ํŠธ๋ฆฌ) ์ž๋ฃŒ๊ตฌ์กฐ๋‹ค. ์ด์ง„ ํŠธ๋ฆฌ๋Š” ๋‘๊ฐœ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง„ ํŠธ๋ฆฌ ํ˜•ํƒœ!

Tree ๊ตฌ์กฐ๋Š” ๋ฐ์ดํ„ฐ์˜ ์ €์žฅ์˜ ์˜๋ฏธ ๋ณด๋‹ค๋Š” ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ํšจ๊ณผ์ ์œผ๋กœ ํƒ์ƒ‰ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค. ์ผ๋ฐ˜ list๋Š” ๊ฒ€์ƒ‰์ด O(N)์ธ๋ฐ์— ๋น„ํ•ด ์ด์ง„ ํŠธ๋ฆฌ๋Š” O(log N) ์ด๋ฏ€๋กœ ๋ฆฌ์ŠคํŠธ ๋ณด๋‹ค ๊ฒ€์ƒ‰์ด ํ›จ์”ฌ ํšจ์œจ ์ ์ด๋‹ค.

  • ํŠธ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋Œ€์ƒ์ •๋ณด์˜ ๊ฐ ํ•ญ๋ชฉ๋“ค์„ ๊ณ„์ธต์ ์œผ๋กœ ์—ฐ๊ด€๋˜๋„๋ก ๊ตฌ์กฐํ™” ์‹œํ‚ค๊ณ ์ž ํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋น„์„ ํ˜• ์ž๋ฃŒ๊ตฌ์กฐ
  • ๋ฐ์ดํ„ฐ ์š”์†Œ๋“ค์˜ ๋‹จ์ˆœํ•œ ๋‚˜์—ด์ด ์•„๋‹Œ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ๋กœ ํ‘œํ˜„
  • ํŠธ๋ฆฌ๋Š” ๊ทธ๋ž˜ํ”„(Graph)์˜ ํ•œ ์ข…๋ฅ˜์ด๋ฉฐ ์‚ฌ์ดํด์ด ์—†์Œ
  • ๊ณ„์ธต์ ์ธ ๊ด€๊ณ„์˜ ํ‘œํ˜„์— ์“ฐ์ด๊ณ , ์œˆ๋„์šฐ์™€ ๋ฆฌ๋ˆ…์Šค์˜ ํŒŒ์ผ์‹œ์Šคํ…œ ๊ตฌ์กฐ๋„ ํŠธ๋ฆฌ๋กœ ํ‘œํ˜„. ๋Œ€์šฉ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ• ๋•Œ๋„ ๋งŽ์ด ์“ฐ์ž„

2. ์šฉ์–ด

ํŠธ๋ฆฌ์˜ ์†์„ฑ ์ค‘ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์ด '๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋…ธ๋“œ๋Š” ๋‹จ ํ•˜๋‚˜์˜ ๋ถ€๋ชจ๋…ธ๋“œ๋งŒ์„ ๊ฐ€์ง„๋‹ค'๋Š” ๊ฒƒ์ด๋‹ค. ๊ธฐ๋ณธ ๊ฐœ๋…์€ ๋…ธ๋“œ์™€ ๋ฃจํŠธ ๋…ธ๋“œ์ด๊ณ , ๋‚˜๋จธ์ง€ ๊ฐœ๋…์— ๋Œ€ํ•ด์„œ๋„ ์ •๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  • Node : ํŠธ๋ฆฌ ๊ตฌ์กฐ์˜ ๊ต์ . Node๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๋˜ํ•œ ์ž์‹๋…ธ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ๋…ธ๋“œ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • Root Node: ํŠธ๋ฆฌ๊ตฌ์กฐ์˜ ๊ฐ€์žฅ ์œ„ ๋…ธ๋“œ. ์ฆ‰ ์‹œ์ž‘์ ์ด ๋˜๋Š” ๋…ธ๋“œ.

  • Edge: ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋“œ์™€ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์„ .
  • level: ํŠธ๋ฆฌ์˜ ํŠน์ • ๊นŠ์ด๋ฅผ ๊ฐ€์ง€๋Š” ๋…ธ๋“œ์˜ ์ง‘ํ•ฉ.
  • degree: ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐœ์ˆ˜/๊ฐ ๋…ธ๋“œ๊ฐ€ ์ง€๋‹Œ ๊ฐ€์ง€์˜ ์ˆ˜.
  • Internal Node : Leaf๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•œ ์ค‘๊ฐ„์— ์œ„์น˜ํ•œ ๋…ธ๋“œ.
  • Leaf Node: ํ•˜์œ„์— ๋‹ค๋ฅธ ๋…ธ๋“œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๋…ธ๋“œ.

3. ํŠธ๋ฆฌ์˜ ํƒ์ƒ‰

ํŠธ๋ฆฌ์˜ ์ˆœํšŒ๋ž€ ํŠธ๋ฆฌ์˜ ๊ฐ ๋…ธ๋“œ๋ฅผ ์ฒด๊ณ„์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐฉ๋ฌธํ•˜๋Š” ๊ณผ์ •์„ ๋งํ•œ๋‹ค. ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ์ˆœ์„œ์— ๋”ฐ๋ผ ์ „์œ„์ˆœํšŒ, ์ค‘์œ„ ์ˆœํšŒ, ํ›„์œ„์ˆœํšŒ ์„ธ๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค. ์ด๋ฏธ์ง€ ๋ฐ ๋‚ด์šฉ์€ ์œ„ํ‚คํ”ผ๋””์•„!

  1. ์ „์œ„์ˆœํšŒ(preorder, ๊นŠ์ด ์šฐ์„  ์ˆœํšŒ): ๋ฃจํŠธ์—์„œ ์‹œ์ž‘ํ•ด ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ์œ„>์•„๋ž˜๋กœ ๋‹ค ๋Œ๊ณ  ์˜ค๋ฅธ ์ชฝ์œผ๋กœ!
  2. ์ค‘์œ„์ˆœํšŒ(inorder, ๋Œ€์นญ ์ˆœํšŒ): ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ๊ฐ€์šด๋ฐ๋ถ€ํ„ฐ ์•„๋ž˜>์œ„ ์ˆœ์œผ๋กœ ๋Œ๊ณ  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ๋’ค, ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ์•„๋ž˜>์œ„ ์ˆœ์œผ๋กœ ์ˆœํšŒํ•œ๋‹ค.
  3. ํ›„์œ„ ์ˆœํšŒ(postorder): ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ๋ฆฌํ”„ ๋…ธ๋“œ๋ถ€ํ„ฐ ๋Œ๊ณ , ์˜ค๋ฅธ์ชฝ์„ ๋ˆ ๋’ค์— ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  4. ๋ ˆ๋ฒจ ์ˆœ์„œ ์ˆœํšŒ(level order, ๋„ˆ๋น„ ์šฐ์„  ์ˆœํšŒ): ๋ ˆ๋ฒจ ์ˆœ์„œ ์ˆœํšŒ(level-order)๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋‚ฎ์€ ๋ ˆ๋ฒจ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ์ˆœํšŒํ•œ๋‹ค.

์˜ˆ์‹œ

์ „์œ„ ์ˆœํšŒ: F, B, A, D, C, E, G, I, H (root, left, right)
์ค‘์œ„ ์ˆœํšŒ: A, B, C, D, E, F, G, H, I (left, root, right)
ํ›„์œ„ ์ˆœํšŒ: A, C, E, D, B, H, I, G, F (left, right, root)
๋ ˆ๋ฒจ ์ˆœ์„œ ์ˆœํšŒ: F, B, G, A, D, I, C, E, H

4. ์ด์ง„ ํŠธ๋ฆฌ์™€ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ

  • ์ด์ง„ ํŠธ๋ฆฌ๋Š” ์ตœ๋Œ€ ์ฐจ์ˆ˜๊ฐ€ 2์ธ ํŠธ๋ฆฌ๋ฅผ ๋งํ•œ๋‹ค. (=๊ฐ ๋…ธ๋“œ๊ฐ€ ์ตœ๋Œ€ 2๊ฐœ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค)
  • ์ด๋Š” ํ•˜๋‚˜์˜ ๋…ธ๋“œ์— LEFT or RIGHT๋งŒ ์กด์žฌํ•œ๋‹ค๊ณ  ํ‘œํ˜„ํ•œ๋‹ค. left node๋Š” ๋ถ€๋ชจ node์˜ ๊ฐ’ ๋ณด๋‹ค ์ ์€ ๊ฐ’์ด ์ €์žฅ๋˜๊ณ  right node๋Š” ๊ฐ™๊ฑฐ๋‚˜ ํฐ ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.

4.1 ์ด์ง„ ํŠธ๋ฆฌ

- ํŽธํ–ฅ ์ด์ง„ ํŠธ๋ฆฌ

skewed binary tree. ํŽธํ–ฅ์ด์ง„ ํŠธ๋ฆฌ๋Š” ํ•˜๋‚˜์˜ ์ฐจ์ˆ˜๋กœ๋งŒ ์ด๋ค„์ ธ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•œ๋‹ค. ์ด๋Ÿฐ ๊ตฌ์กฐ๋Š” ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ ์„ ํ˜• ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— Leaf Node (๊ฐ€์žฅ ๋ ๋…ธ๋“œ)ํƒ์ƒ‰์‹œ ๊ฒฐ๊ตญ ๋ชจ๋‘ ์ฝ์–ด ๋“ค์—ฌ์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์–ด์„œ ํšจ์œจ์ด ๋–จ์–ด์ง„๋‹ค๊ณ  ๋งํ•œ๋‹ค. ์ด๊ฐ™์€ ์ ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด '๋†’์ด ๊ท ํ˜• ํŠธ๋ฆฌ'๋ผ๋Š” ๊ฒƒ์ด ์žˆ๋‹ค.

- ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ

full binary tree. ํฌํ™”์ด์ง„ ํŠธ๋ฆฌ๋Š” Leaf Node๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ์ฐจ์ˆ˜๊ฐ€ ๋‘๊ฐœ๋กœ ์ด๋ค„์ง„ ๊ฒฝ์šฐ๋ฅผ ๋งํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ํ•ด๋‹น ์ฐจ์ˆ˜์— ๋ช‡๊ฐœ์˜ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๋ฐ”๋กœ ์•Œ์ˆ˜ ์žˆ์–ด ๊ฐœ์ˆ˜ ํŒŒ์•…์ด ์šฉ์ดํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

- ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ

complete binary tree. ํฌํ™” ์ด์ง„ํŠธ๋ฆฌ์™€ ๊ฐ™์€ ๊ฐœ๋…์œผ๋กœ ์ƒ์„ฑํ•˜์ง€๋งŒ ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ์™ผ์ชฝ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ์ƒ์„ฑ๋˜๋Š” ์ด์ง„ ํŠธ๋ฆฌ๋ฅผ ๋งํ•œ๋‹ค.

4.2 ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ

- ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ

binary search tree. ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์—์„œ๋Š” ํ•ญ์ƒ ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ์™ผ์ชฝ ์ž์‹๋ณด๋‹ค๋Š” ํฌ๊ณ , ์˜ค๋ฅธ์ชฝ ์ž์‹๋ณด๋‹ค๋Š” ์ž‘๋‹ค.
์ด๋Ÿฌํ•œ ํŠน์„ฑ ๋•๋ถ„์— ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ์—์„œ๋Š” ํ•œ๋ฒˆ ํ™•์ธํ• ๋•Œ ใ…๋งˆ๋‹ค ๋ณด์•„์•ผ ํ•˜๋Š” ์›์†Œ์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ ˆ๋ฐœ์”ฉ ์ค„์–ด๋“ ๋‹ค๋Š” ์ ์—์„œ '์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ'์ธ ๊ฒฝ์šฐ ํƒ์ƒ‰์‹œ๊ฐ„์— O(logN)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค.

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์—์„œ ํƒ์ƒ‰(traverse)์„ ํ•  ๋•Œ๋Š” ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’์ด ๋ถ€๋ชจ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ ์™ผ์ชฝ ์ž์‹์œผ๋กœ, ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’์ด ๋ถ€๋ชจ ๋…ธ๋“œ๋ณด๋‹ค ํด ๊ฒฝ์šฐ ์˜ค๋ฅธ์ชฝ ์ž์‹์œผ๋กœ ์ด์–ด ๋‚˜๊ฐ€๋ฉด์„œ ๋ฐฉ๋ฌธ ํ•œ๋‹ค. ์ด์ง„ ํƒ์ƒ‰ํŠธ๋ฆฌ๋Š” ์ด์ง„ ํƒ์ƒ‰์ด ํ•ญ์ƒ ๋™์ž‘ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์—ฌ ํƒ์ƒ‰ ์†๋„๋ฅผ ๊ทน๋Œ€ํ™”์‹œํ‚จ ์ž๋ฃŒ๊ตฌ์กฐ๋‹ค.

class Node:

    def __init__(self, data):

        self.left = None
        self.right = None
        self.data = data

    def insert(self, data):

        if self.data:
            if data < self.data:
                if self.left is None:
                    self.left = Node(data)
                else:
                    self.left.insert(data)
            elif data > self.data:
                if self.right is None:
                    self.right = Node(data)
                else:
                    self.right.insert(data)
        else:
            self.data = data

    def findval(self, lkpval):
        if lkpval < self.data:
            if self.left is None:
                return str(lkpval)+" Not Found"
            return self.left.findval(lkpval)
        elif lkpval > self.data:
            if self.right is None:
                return str(lkpval)+" Not Found"
            return self.right.findval(lkpval)
        else:
            print(str(self.data) + ' is found')

    def PrintTree(self):
        if self.left:
            self.left.PrintTree()
        print(self.data)
        if self.right:
            self.right.PrintTree()


root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
print(root.findval(7))
print(root.findval(14))
profile
์ด์‚ฌ๊ฐ„ ๋ธ”๋กœ๊ทธ: yenilee.github.io

0๊ฐœ์˜ ๋Œ“๊ธ€