๐Ÿ’กย ํŠธ๋ฆฌ (Trees)

์ •์  (node) ๊ณผ ๊ฐ„์„  (edge) ์„ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ๋ฐฐ์น˜ ํ˜•ํƒœ๋ฅผ ์ถ”์ƒํ™”ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

  • 2์ฐจ์›์˜ ์ž๋ฃŒ ๊ตฌ์กฐ
  • ์ •๋ณด๋ฅผ ์กฐ์งํ™”ํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๋Š”๋ฐ ์šฉ์ดํ•˜๊ฒŒ ์ด์šฉ ๊ฐ€๋Šฅ
๐Ÿ”Ž Check Point ๐Ÿ”

๐Ÿ’ญย  LinkedList, Array - ๋‹ค๋ฅธ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ๋ชจํ‹ฐ๋ธŒ๊ฐ€ ๋˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ (์ปดํ“จํ„ฐ ์นœํ™”์ )

๐Ÿ’ญย  Stack, Queue, Deque - ์‹œ์Šคํ…œ ๋‚ด๋ถ€์ ์ธ ๊ตฌํ˜„์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์„ฑ๋Šฅ์— ์ถฉ์‹คํ•œ ์ž๋ฃŒ๊ตฌ์กฐ (์ปดํ“จํ„ฐ ์นœํ™”์ )

๐Ÿ’ญย  Trees - ์‚ฌ๋žŒ์ด ์‚ฌ์šฉํ•˜๊ธฐ์— ํŽธ๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ ํƒ„์ƒํ•œ ์ž๋ฃŒ๊ตฌ์กฐ (์‚ฌ๋žŒ ์นœํ™”์ )


๐Ÿ“Œย ์šฉ์–ด ์ •๋ฆฌ


  • ๋ฃจํŠธ (Root) ๋…ธ๋“œ: ์ œ์ผ ์œ„์— ์œ„์น˜ํ•œ ๋…ธ๋“œ - A

  • ๋ฆฌํ”„ (Leaf) ๋…ธ๋“œ: ๋” ์ด์ƒ ๊ฐ€์ง€์น  ์ˆ˜๊ฐ€ ์—†๋Š” ๋งจ ๋ฐ‘์— ์žˆ๋Š” ๋…ธ๋“œ - H, I, J, F, G

  • ๋‚ด๋ถ€ (Internal) ๋…ธ๋“œ: ๋ฃจํŠธ๋„ ๋ฆฌํ”„๋„ ์•„๋‹Œ ์ค‘๊ฐ„์— ์žˆ๋Š” ๋…ธ๋“œ - B, C, D, E

  • ๋ถ€๋ชจ (Parenet) ๋…ธ๋“œ: ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค ์‚ฌ์ด์—์„œ ๋ฃจํŠธ ๋…ธ๋“œ ์ชฝ์— ๊ฐ€๊นŒ์šด ๋…ธ๋“œ - ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ D, H, I ์˜ ๊ด€๊ณ„์—์„œ ๋ณด๋ฉด D ๊ฐ€ H, I ์˜ ๋ถ€๋ชจ ๋…ธ๋“œ์ด๋‹ค.

  • ์ž์‹ (Child) ๋…ธ๋“œ: ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค ์‚ฌ์ด์—์„œ ๋ฆฌํ”„ ๋…ธ๋“œ ์ชฝ์— ๊ฐ€๊นŒ์šด ๋…ธ๋“œ - D, H, I ๊ด€๊ณ„์—์„œ H, I ๊ฐ€ D ์˜ ์ž์‹ ๋…ธ๋“œ์ด๋‹ค.

  • slibing ๊ด€๊ณ„: ๊ฐ™์€ ๋ถ€๋ชจ ์•„๋ž˜์˜ ๋…ธ๋“œ๋“ค ๋ผ๋ฆฌ์˜ ๊ด€๊ณ„ - F, G ์˜ ๊ด€๊ณ„

  • ์กฐ์ƒ (Ancestor): ์ž์‹ ๋…ธ๋“œ ์ž…์žฅ์—์„œ ๋ถ€๋ชจ์˜ ๋ถ€๋ชจ โ€ฆ ๋กœ ์˜ฌ๋ผ๊ฐ€๋Š” ๋…ธ๋“œ๋“ค - H, I ์ž…์žฅ์—์„  A, B, D ๊ฐ€ ์กฐ์ƒ์ด๋‹ค.

  • ํ›„์† (Descendant): ๋ถ€๋ชจ ๋…ธ๋“œ ์ž…์žฅ์—์„œ ์ž์‹์˜ ์ž์‹ โ€ฆ ๋กœ ๋‚ด๋ ค๊ฐ€๋Š” ๋…ธ๋“œ๋“ค - A ์ž…์žฅ์—์„  ๋‚˜๋จธ์ง€๋…ธ๋“œ๋“ค์ด ํ›„์†์ด๋‹ค.

  • ๋…ธ๋“œ์˜ ์ˆ˜์ค€ (Level): ๋ฃจํŠธ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ํ•ด๋‹น ๋…ธ๋“œ๊นŒ์ง€ ๋„๋‹ฌํ–ˆ์„ ๋•Œ ๊ฑฐ์น˜๋Š” ๊ฐ„์„ ์˜ ๊ฐฏ์ˆ˜๋กœ ์ •์˜ํ•œ๋‹ค. - ๋ฃจํŠธ ๋…ธํŠธ: Level 0, ๋ฐ‘์œผ๋กœ ๋‚ด๋ ค๊ฐ€๋ฉด์„œ level ์ด 1 ์”ฉ ์˜ฌ๋ผ๊ฐ„๋‹ค.

  • ํŠธ๋ฆฌ์˜ ๋†’์ด (Height) = ์ตœ๋Œ€ ์ˆ˜์ค€ (level) + 1, ๊นŠ์ด (depth) ๋ผ๊ณ ๋„ ํ•œ๋‹ค - ์—ฌ๊ธฐ์„œ์˜ ๋†’์ด๋Š” 4์ด๋‹ค.

  • ๋ถ€๋ถ„ ํŠธ๋ฆฌ (์„œ๋ธŒํŠธ๋ฆฌ - Subtree): ํŠธ๋ฆฌ์—์„œ ์–ด๋Š ํ•œ ๋…ธ๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ทธ ์•„๋ž˜์— ์žˆ๋Š” ๊ฒƒ๋“ค์„ ์ƒˆ๋กœ์šด ํŠธ๋ฆฌ๋กœ ๋ณด๋Š” ๊ฒƒ - D ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ดค์„ ๋•Œ D, H, I ๋ฅผ ์ƒˆ๋กœ์šด ๋ถ€๋ถ„ํŠธ๋ฆฌ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • ๋…ธ๋“œ์˜ ์ฐจ์ˆ˜ (Degree): ์ž์‹ (์„œ๋ธŒํŠธ๋ฆฌ) ์˜ ์ˆ˜ - degree: 0 ์ธ ๊ฒƒ์€ ๋ฆฌํ”„ ๋…ธ๋“œ์ด๋‹ค.

  • ๊ฐ ๋…ธ๋“œ๋Š” ์ž์‹ ๋…ธ๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ถ€๋ชจ ๋…ธ๋“œ๋Š” ๋‹จ ํ•˜๋‚˜๋งŒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ“Œ ์šฉ๋„


  • ํŒŒ์ผ์‹œ์Šคํ…œ ๊ตฌ์กฐ์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ
  • ๊ณ„์ธต์ ์ธ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ๋˜๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ž๋ฃŒ์—์„œ ์‚ฌ์šฉ


๐Ÿ“Œย ์ด์ง„ ํŠธ๋ฆฌ (Binary Tree)

๋ชจ๋“  ๋…ธ๋“œ์˜ ์ฐจ์ˆ˜๊ฐ€ 2 ์ดํ•˜์ธ ํŠธ๋ฆฌ์ด๋‹ค.

  • ๋นˆ ํŠธ๋ฆฌ (empty tree)
  • ๋ฃจํŠธ ๋…ธ๋“œ + ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ + ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ (์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ๋˜ํ•œ ์ด์ง„ํŠธ๋ฆฌ์ด๋‹ค.)

๐Ÿ’ญย ์žฌ๊ท€์ ์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ“Œ ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ (Full Binary Tree)

๋ชจ๋“  ๋ ˆ๋ฒจ์—์„œ ๋…ธ๋“œ๋“ค์ด ๋ชจ๋‘ ์ฑ„์›Œ์ ธ ์žˆ๋Š” ์ด์ง„ ํŠธ๋ฆฌ์ด๋‹ค.

๐Ÿ’ญย ๋ฆฌํ”„ ๋…ธ๋“œ ๋“ค์ด ๊ฐ™์€ ๋†’์ด์— ์žˆ๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค.

๐Ÿ’ญย ๋†’์ด๊ฐ€ $k$ ์ด๊ณ , ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๊ฐ€ $2^k -1$ ์ธ ์ด์ง„ ํŠธ๋ฆฌ์ด๋‹ค.


๐Ÿ“Œ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ (Complete Binary Tree)

๋ฆฌํ”„ ๋…ธ๋“œ๋“ค์ด ์™ผ์ชฝ๋ถ€ํ„ฐ ์ฑ„์›Œ์ง€๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค. ๋†’์ด๊ฐ€ $k$ ์ธ ์™„์ „ ์ด์ง„ํŠธ๋ฆฌ๋Š” level ์ด $k -2$ ๊นŒ์ง€๋Š” ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ 2 ๊ฐœ์˜ ์ž์‹์„ ๊ฐ€์ง„ ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ์ด๊ณ , level ์ด $k-1$ ๋ถ€ํ„ฐ๋Š” ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„ ์™ผ์ชฝ๋ถ€ํ„ฐ ๋…ธ๋“œ๊ฐ€ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฑ„์›Œ์ ธ ์žˆ๋Š” ์ด์ง„ ํŠธ๋ฆฌ์˜ ํ˜•ํƒœ๋ฅผ ๋„๊ณ  ์žˆ๋‹ค.

๐Ÿ’ญย ํŠธ๋ฆฌ๋ฅผ ์ด์šฉํ•œ ๊ฒ€์ƒ‰์—์„œ๋Š” ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ์— ๊ฐ€๊นŒ์šธ ์ˆ˜๋ก ๋†’์€ ์„ฑ๋Šฅ์„ ๋‚ด๊ธฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฐ์น˜ํ•  ๋•Œ๋Š” ์ตœ๋Œ€ํ•œ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋ชจ์Šต๊ณผ ๊ฐ€๊น๊ฒŒ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.


๐Ÿ“Œ ์ด์ง„ ํŠธ๋ฆฌ์˜ ์ถ”์ƒ์  ์ž๋ฃŒ๊ตฌ์กฐ

์—ฐ์‚ฐ์˜ ์ •์˜

  • size() - ํ˜„์žฌ ํŠธ๋ฆฌ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๋…ธ๋“œ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•จ
  • depth() - ํ˜„์žฌ ํŠธ๋ฆฌ์˜ ๊นŠ์ด (๋˜๋Š” ๋†’์ด; height) ๋ฅผ ๊ตฌํ•จ
  • traversal() - ์ •ํ•ด์ง„ ์ˆœ์„œ๋Œ€๋กœ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•ด์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ


์ด์ง„ ํŠธ๋ฆฌ์˜ ๊ตฌํ˜„ - ๋…ธ๋“œ (Node)

Node

  • Data
  • Left Child
  • Right Child
class Node:
	def __init__(self, item):
		self.data = item
		self.left = None
		self.right = None


์ด์ง„ ํŠธ๋ฆฌ์˜ ๊ตฌํ˜„ - ํŠธ๋ฆฌ (Tree)

# ์ด์ง„ ํŠธ๋ฆฌ์—์„œ๋Š” ๋ฃจํŠธ ๋…ธ๋“œ๋งŒ ์ฃผ์–ด์ง€๋ฉด ๊ฐ„์„ ์„ ๋”ฐ๋ผ ๋‚ด๋ ค๊ฐ€๊ธฐ์— ๋ฃจํŠธ ๋…ธ๋“œ๋งŒ ์ง€์ •ํ•ด ์คŒ
class BinaryTree:
	def __init__(self, r):
		self.root = r


์ด์ง„ ํŠธ๋ฆฌ์˜ ๊ตฌํ˜„ - size()

# ์žฌ๊ท€์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ์Œ!
# ์ „์ฒด ์ด์ง„ ํŠธ๋ฆฌ์˜ size() = left subtree ์˜ size() + right subtree ์˜ size() + 1 (์ž๊ธฐ ์ž์‹ )

class Node:
	def size(self):
		l = self.left.size() if self.left else 0
		r = self.right.size() if self.right else 0
		return l + r + 1

class BinaryTree:
	def size(self):
		if self.root:
			return self.root.size()
		else: # empty tree ์ผ ๋•Œ
			return 0  


์ด์ง„ ํŠธ๋ฆฌ์˜ ๊ตฌํ˜„ - depth()

# ์žฌ๊ท€์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ์Œ!
# ์ „์ฒด ์ด์ง„ ํŠธ๋ฆฌ์˜ depth() = left subtree ์˜ depth() ์™€ right subtree ์˜ depth() ์ค‘ ๋” ํฐ ๊ฒƒ + 1

class Node:
		def depth(self):
			...

class BinaryTree:
		def depth(self):
			if self.root:
				return



class Node:

    def __init__(self, item):
        self.data = item
        self.left = None
        self.right = None


    def size(self):
        l = self.left.size() if self.left else 0
        r = self.right.size() if self.right else 0
        return l + r + 1


    def depth(self):
        l = self.left.depth() if self.left else 0
        r = self.right.depth() if self.right else 0
        return l + 1 if l >= r else r + 1


class BinaryTree:

    def __init__(self, r):
        self.root = r

    def size(self):
        if self.root:
            return self.root.size()
        else:
            return 0


    def depth(self):
        if self.root:
            return self.root.depth()
        else:
            return 0


๐Ÿ“Œ ์ด์ง„ ํŠธ๋ฆฌ์˜ ์ˆœํšŒ (Traversal)

  • ๊นŠ์ด ์šฐ์„  ์ˆœํšŒ (Depth first traversal)
    • ์ค‘์œ„ ์ˆœํšŒ (In - order traversal)
    • ์ „์œ„ ์ˆœํšŒ (Pre - order traversal)
    • ํ›„์œ„ ์ˆœํšŒ (Post - order traversal)
  • ๋„ˆ๋น„ ์šฐ์„  ์ˆœํšŒ (Breadth first traversal)

์ค‘์œ„ ์ˆœํšŒ (In - order Traversal)

์ˆœํšŒ ์ˆœ์„œ:

  1. Left subtree
  2. ์ž๊ธฐ ์ž์‹ 
  3. Right subtree

์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ๋ฃจํŠธ๋ฅผ ๊ฑฐ์ณ ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ์ˆœํšŒ์ด๋‹ค.

์œ„ ๊ทธ๋ฆผ์—์„  C, B, D ๋ฅผ ๋ฐฉ๋ฌธํ•˜์—ฌ ์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ๋ฅผ ๊ฑฐ์ณ ๋ฃจํŠธ๋…ธ๋“œ์ธ A๋ฅผ ๋ฐฉ๋ฌธ, ์ดํ›„์— ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ ์ค‘ ๊ฐ€์žฅ ์™ผ์ชฝ์— ์žˆ๋Š” F๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ์ดํ›„ E, G ์ˆœ์„œ๋กœ ๋ฐฉ๋ฌธ์„ ํ•˜๊ฒŒ ๋œ๋‹ค.

class Node:
	def inorder(self):
		traversal = [] # ๋ฆฌํ„ดํ•˜๋ ค๋Š” ๋ฐฉ๋ฌธ์ˆœ์„œ๊ฐ€ ๋‹ด๊ธธ ๋ฆฌ์ŠคํŠธ
		if self.left:
			traversal += self.left.inorder()
		traversal.append(self.data)
		if self.right:
			traversal += self.right.inorder()
		return traversal

class BinaryTree:
	def inorder(self):
		if self.root:
			return self.root.inorder()
		else:
			return []
		


์ „์œ„ ์ˆœํšŒ (Pre - order Traversal)

์ˆœํšŒ ์ˆœ์„œ:

  1. ์ž๊ธฐ ์ž์‹ 
  2. Left subtree
  3. Right subtree

๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ, ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐฉ๋ฌธํ•˜๋Š” ์ˆœํšŒ์ด๋‹ค. ์œ„ ๊ทธ๋ฆผ์—์„  ๋ฃจํŠธ ๋…ธ๋“œ์ธ A ๋ฅผ ์‹œ์ž‘์œผ๋กœ B ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ๋‹ค์‹œ B ์˜ ์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ์ธ C ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ์ธ D๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋œ๋‹ค. ์ด ํ›„์— ์ˆœ์ฐจ์ ์œผ๋กœ E, F, G ๋ฅผ ๋ฐฉ๋ฌธํ•œ๋‹ค.

class Node:

    def __init__(self, item):
        self.data = item
        self.left = None
        self.right = None


    def inorder(self):
        traversal = []
        if self.left:
            traversal += self.left.inorder()
        traversal.append(self.data)
        if self.right:
            traversal += self.right.inorder()
        return traversal


    def preorder(self):
        traversal = []
        traversal.append(self.data)
        if self.left:
            traversal += self.left.preorder() # left child ๊ฐ€ ์žˆ๋Š” ์ง€ ํ™•์ธํ•˜๋ ค๋Š” ๊ฒƒ
        if self.right:
            traversal += self.right.preorder() # right child ๊ฐ€ ์žˆ๋Š” ์ง€ ํ™•์ธํ•˜๋ ค๋Š” ๊ฒƒ
        return traversal


class BinaryTree:

    def __init__(self, r):
        self.root = r


    def inorder(self):
        if self.root:
            return self.root.inorder()
        else:
            return []


    def preorder(self):
        return self.root.preorder() if self.root else []


ํ›„์œ„ ์ˆœํšŒ (Post - order Traversal)

์ˆœํšŒ ์ˆœ์„œ:

  1. Left subtree
  2. Right subtree
  3. ์ž๊ธฐ ์ž์‹ 

์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ์ˆœํšŒ์ด๋‹ค. ์œ„ ๊ทธ๋ฆผ์—์„  ์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ์ธ C ๋ฅผ ์ œ์ผ ๋จผ์ € ๋ฐฉ๋ฌธํ•˜๊ณ  C ์—์„œ์˜ ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ์ธ D๋ฅผ ๋ฐฉ๋ฌธ, ์ดํ›„ B ๋ฅผ ๋ฐฉ๋ฌธํ•œ๋‹ค.๊ทธ๋ฆฌ๊ณ  ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ ์ค‘ ์ œ์ผ ์™ผ์ชฝ ํ•˜์œ„ํŠธ๋ฆฌ์ธ F ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ์ˆœ์ฐจ์ ์œผ๋กœ G, E, A ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋œ๋‹ค.

class Node:

    def __init__(self, item):
        self.data = item
        self.left = None
        self.right = None


    def inorder(self):
        traversal = []
        if self.left:
            traversal += self.left.inorder()
        traversal.append(self.data)
        if self.right:
            traversal += self.right.inorder()
        return traversal


    def postorder(self):
        traversal = []
        if self.left:
            traversal += self.left.postorder()
        if self.right:
            traversal += self.right.postorder()
        traversal.append(self.data)
        return traversal


class BinaryTree:

    def __init__(self, r):
        self.root = r


    def inorder(self):
        if self.root:
            return self.root.inorder()
        else:
            return []


    def postorder(self):
        return self.root.postorder() if self.root else []


๋„ˆ๋น„ ์šฐ์„  ์ˆœํšŒ (Breadth First Traversal) (= ๋ ˆ๋ฒจ ์ˆœ์„œ ์ˆœํšŒ (Levelorder Traversal))

์ˆœํšŒ ์ˆœ์„œ:

  1. level ์ด ๋‚ฎ์€ ๋…ธ๋“œ๋ฅผ ์šฐ์„ ์œผ๋กœ ๋ฐฉ๋ฌธ
  2. ๊ฐ™์€ level ์˜ ๋…ธ๋“œ๋“ค ์‚ฌ์ด์—์„œ๋Š” ์™ผ์ชฝ ๋…ธ๋“œ์—์„œ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ ์ˆœ์œผ๋กœ ๋ฐฉ๋ฌธ

level ์ด ๊ฐ€์žฅ ๋‚ฎ์€ ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋ฆฌํ”„ ๋…ธ๋“œ๊นŒ์ง€ ๋‚ด๋ ค๊ฐ€๋Š” ์ˆœํšŒํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด ๋•Œ, ๊ฐ™์€ level ์—์„œ๋Š” ์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ ์ˆœ์œผ๋กœ ๋ฐฉ๋ฌธํ•œ๋‹ค. ์œ„ ๊ทธ๋ฆผ์—์„  ๋ฃจํŠธ ๋…ธ๋“œ์ธ A ๋ฅผ ์‹œ์ž‘์œผ๋กœ ๋‹ค์Œ level ์ธ B, C ์ค‘ ์™ผ์ชฝ๋ถ€ํ„ฐ B, C ์ˆœ์œผ๋กœ ๋ฐฉ๋ฌธํ•˜๊ณ  ์ด ํ›„ ์ˆœ์ฐจ์ ์œผ๋กœ D, E, F, G, H, I, J, K, L ์„ ๋ฐฉ๋ฌธํ•œ๋‹ค.

๐Ÿ’ญย ์žฌ๊ท€์  ๋ฐฉ๋ฒ•์ด ์ ํ•ฉํ•˜์ง€ ์•Š๊ณ , ๋‚˜์ค‘์— ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ๊ธฐ๋กํ•ด ๋‘์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.


๋„ˆ๋น„ ์šฐ์„  ์ˆœํšŒ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ค๊ณ„

  • ํ๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ํ์— ์‚ฝ์ž…ํ•œ๋‹ค.
  • ํ์—์„œ ๊บผ๋‚ธ ํ›„ ํ•ด๋‹น ๋…ธ๋“œ ๋ฐฉ๋ฌธํ•œ๋‹ค.
  • ํ•ด๋‹น ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ์— ์‚ฝ์ž…ํ•œ๋‹ค.
  • ํ•ด๋‹น ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ์— ์‚ฝ์ž…ํ•œ๋‹ค.
  • ๋‹ค ํ™•์ธํ–ˆ๋‹ค๋ฉด ํ์— ์žˆ๋Š” ๊ฐ’์„ ๋นผ๋‚ธ๋‹ค.
  • ์œ„์™€ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์นœ ํ›„ ํ๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด ์ข…๋ฃŒํ•œ๋‹ค.


๋„ˆ๋น„ ์šฐ์„  ์ˆœํšŒ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„

class BinaryTree:
	def bft(self):
		

1. (์ดˆ๊ธฐํ™”) traversal <- ๋นˆ ๋ฆฌ์ŠคํŠธ, q <- ๋นˆํ
2. ๋นˆ ํŠธ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ฉด, root node๋ฅผ ํ์— ์ถ”๊ฐ€ (enqueue)
3. q ๊ฐ€ ๋น„์–ด ์žˆ์ง€ ์•Š์€ ๋™์•ˆ ์ง„ํ–‰
	3.1 node <- q ์—์„œ ์›์†Œ๋ฅผ ์ถ”์ถœ (dequeue)
	3.2 node ๋ฅผ ๋ฐฉ๋ฌธ (append)
	3.3 node ์˜ ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ์ž์‹ (์žˆ์œผ๋ฉด) ๋“ค์„ q ์— ์ถ”๊ฐ€
4. q๊ฐ€ ๋นˆ ํ๊ฐ€ ๋˜๋ฉด ๋ชจ๋“  ๋…ธ๋“œ ๋ฐฉ๋ฌธ ์™„๋ฃŒ

class ArrayQueue:

    def __init__(self):
        self.data = []

    def size(self):
        return len(self.data)

    def isEmpty(self):
        return self.size() == 0

    def enqueue(self, item):
        self.data.append(item)

    def dequeue(self):
        return self.data.pop(0)

    def peek(self):
        return self.data[0]


class Node:

    def __init__(self, item):
        self.data = item
        self.left = None
        self.right = None


class BinaryTree:

    def __init__(self, r):
        self.root = r


    def bft(self):
        traversal = []
        Queue = ArrayQueue()
        if self.root:
            Queue.enqueue(self.root)

        while not Queue.isEmpty():
            q = Queue.dequeue()
            traversal.append(q.data)
            if q.left:
                Queue.enqueue(q.left)
            if q.right:
                Queue.enqueue(q.right)            
        return traversal