221001_HackerRank : Tree - Search

Cswยท2022๋…„ 10์›” 1์ผ
0

CodingTest

๋ชฉ๋ก ๋ณด๊ธฐ
1/6

๐ŸŒž Tree Search ๋ฌธ์ œ

Tree: Preorder Traversal
Tree: Inorder Traversal
Tree: Postorder Traversal
Tree: Levelorder Traversal

๐ŸšŠ ๋ฌธ์ œ ๊ณตํ†ต ์‚ฌํ•ญ


๐Ÿšข ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ ํด๋ž˜์Šค

# 1. Node ํด๋ž˜์Šค ์„ ์–ธ
class Node:
    def __init__(self, info): 
    	# Node์˜ ๋ฐ์ดํ„ฐ = info
        self.info = info
        # Node์˜ ์™ผ์ชฝ = None
        self.left = None  
        # Node์˜ ์˜ค๋ฅธ์ชฝ = None
        self.right = None 
        # Node์˜ level = None
        self.level = None 

	# init์—์„œ ๊ทœ์ •ํ•œ ํด๋ž˜์Šค ์ž์ฒด ๋‚ด์šฉ์„ ์ถœ๋ ฅ
    def __str__(self):
        return str(self.info) 

# ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ ํด๋ž˜์Šค ์„ ์–ธ
class BinarySearchTree:
    def __init__(self):
    	# root ๋…ธ๋“œ๋ฅผ None์œผ๋กœ ์„ ์–ธ
        self.root = None
	
    # ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ์— ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
    
    def create(self, val):  
    	# root ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด
        if self.root == None:
        	# val ๊ฐ’์„ ๊ฐ–๋Š” ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ root ๋…ธ๋“œ์— ํ• ๋‹นํ•˜๊ณ  ๋๋ƒ„.
            self.root = Node(val)
        #  root ๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด
        else:
        	# ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ root ๋…ธ๋“œ๋กœ ์ง€์ •
            current = self.root
         	# ๊ณ„์† ๋ฐ˜๋ณต
            #   ์‚ฝ์ž…ํ•  ์œ„์น˜๋ฅผ ๋จผ์ € ์ฐพ๊ณ , ์™„๋ฃŒ๋˜๋ฉด ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ val๋กœ ์ง€์ •ํ•˜๋Š” ๋ฐฉ์‹
            while True:
            	# ์‚ฝ์ž…ํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ ๊ฐ’๋ณด๋‹ค ์ž‘๋‹ค๋ฉด โ†’ ์™ผ์ชฝ์œผ๋กœ ๋‚ด๋ ค๊ฐ€์„œ ์‚ฝ์ž…ํ•  ์œ„์น˜๋ฅผ ์ฐพ์Œ.
                if val < current.info:
                	# ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด
                    if current.left:
                    	# ์‚ฝ์ž…ํ•  ํƒ์ƒ‰ ์œ„์น˜๋ฅผ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ๋กœ ๋ณ€๊ฒฝ
                        current = current.left
                    # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด
                    else:
                    	# val ๊ฐ’์„ ๊ฐ–๋Š” ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ์— ํ• ๋‹น.
                        current.left = Node(val)
                        # ๋ฐ์ดํ„ฐ ์‚ฝ์ž…์„ ๋๋ƒˆ์œผ๋‹ˆ ๋ฐ˜๋ณต๋ฌธ ์ข…๋ฃŒ์‹œํ‚ค๊ณ  ๋๋ƒ„.
                        break
                # ์‚ฝ์ž…ํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ ๊ฐ’๋ณด๋‹ค ํฌ๋‹ค๋ฉด
                elif val > current.info:
                	# ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด
                    if current.right:
                    	# ์‚ฝ์ž…ํ•  ํƒ์ƒ‰ ์œ„์น˜๋ฅผ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋กœ ๋ณ€๊ฒฝ
                        current = current.right
                    # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด
                    else:
                    	# val ๊ฐ’์„ ๊ฐ–๋Š” ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ์— ํ• ๋‹น
                        current.right = Node(val)
                        # ๋ฐ์ดํ„ฐ ์‚ฝ์ž…์„ ๋๋ƒˆ์œผ๋‹ˆ ๋ฐ˜๋ณต๋ฌธ ์ข…๋ฃŒ์‹œํ‚ค๊ณ  ๋๋ƒ„.
                        break
                # ์‚ฝ์ž…ํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ ๊ฐ’์ด ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ ๊ฐ’๊ณผ ๋™์ผํ•˜๋‹ค๋ฉด
                else:
                	# ์‚ฝ์ž…ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋‹ˆ ๊ทธ๋ƒฅ ๋๋ƒ„.
                    break

๐Ÿšข Input & Output

# ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ ์„ ์–ธ
tree = BinarySearchTree()
# ์ƒ์„ฑํ•  ๋…ธ๋“œ ๊ฐœ์ˆ˜ ์ž…๋ ฅ๋ฐ›๊ธฐ
t = int(input())
# n ร— 1 ์‚ฌ์ด์ฆˆ์˜ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ์˜ array ์ƒ์„ฑ
arr = list(map(int, input().split()))
# for๋ฌธ์„ ๋Œ๋ฉด์„œ ๋…ธ๋“œ ์ƒ์„ฑ
for i in range(t):
    tree.create(arr[i])

##### ์—ฌ๊ธฐ์— ๋ฌธ์ œ์—์„œ ์›ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ์ฝ”๋“œ ์‹คํ–‰ํ•˜๊ฒŒ ๋จ ####

๐ŸšŠ Tree ์ˆœํšŒ ๊ตฌํ˜„

์ œ์•ฝ์กฐ๊ฑด

Nodes in the tree

์ถœ๋ ฅ ํ˜•์‹

Print the tree's preorder traversal as a single line of space-separated values.

์ž…๋ ฅ ์˜ˆ์‹œ

     1
      \
       2
        \
         5
        /  \
       3    6
        \
         4  

์ถœ๋ ฅ ์˜ˆ์‹œ

# Preorder
	1 2 5 3 4 6 
# Inorder
	1 2 3 4 5 6 
# Postorder
	4 3 6 5 2 1 
# Levelorder
	1 2 5 3 6 4
    

๐ŸšŠ ์ˆœํšŒ ๋ฐฉ์‹๋ณ„ ์‚ดํŽด๋ณด๊ธฐ


๐Ÿšข Preorder

๐Ÿšฅ Root Node โ†’ left Node โ†’ right Node

๐Ÿ“‘ Code

def PreOrder(root):
	# root ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด
	if root:
    	# ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ 
    	print(root.info, end=" ")
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ์—์„œ PreOrder๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰
        # โ†’ ์™ผ์ชฝ์œผ๋กœ ํ•œ ๋‹จ๊ณ„ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ์˜๋ฏธ
        PreOrder(root.left)
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ์—์„œ Preorder๊ฐ€ ๋๋‚ฌ๋‹ค๋ฉด, ์˜ค๋ฅธ์ชฝ์—์„œ PreOrder๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰
        # โ†’ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ ๋‹จ๊ณ„ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ์˜๋ฏธ
        PreOrder(root.right)
  • root ๋…ธ๋“œ์—์„œ ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ 
  • ๊ทธ ๋‹ค์Œ์— ์™ผ์ชฝ ๋…ธ๋“œ๋กœ ๋‚ด๋ ค๊ฐ€์„œ ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
  • ์œ„์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณต
  • ๋”์ด์ƒ ํŒŒ๊ณ ๋“ค ์™ผ์ชฝ ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ๋ฐ”๋กœ ์ด์ „ ๋…ธ๋“œ๋กœ ๋Œ์•„๊ฐ€ ํ•ด๋‹น ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋กœ ๋‚ด๋ ค๊ฐ.
  • ์ด ๊ณผ์ •์„ ๋๊นŒ์ง€ ๋ฐ˜๋ณต

๐Ÿšข Inorder

๐Ÿšฅ left Node โ†’ Root Node โ†’ right Node

๐Ÿ“‘ Code

def inOrder(root):
	# root ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด
	if root:
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ์—์„œ inOrder๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰
        inOrder(root.left)
    	# ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
    	print(root.info, end=" ")
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ์—์„œ inOrder๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰
        inOrder(root.right)
  • root ๋…ธ๋“œ๋ถ€ํ„ฐ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ๋กœ ๋‚ด๋ ค๊ฐ€๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณต
  • ํ˜„์žฌ ๋…ธ๋“œ ๊ธฐ์ค€, ๋”์ด์ƒ ํŒŒ๊ณ ๋“ค ์™ผ์ชฝ ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
  • ๋ฐ”๋กœ ์ด์ „ ๋…ธ๋“œ๋กœ ๋Œ์•„๊ฐ€ ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
  • ๊ทธ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋กœ ๋‚ด๋ ค๊ฐ€์„œ ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
  • ์ด ๊ณผ์ •์„ ๋๊นŒ์ง€ ๋ฐ˜๋ณต

๐Ÿšข Postorder

๐Ÿšฅ Root Node โ†’ left Node โ†’ right Node

๐Ÿ“‘ Code

def postOrder(root):
	# root ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด
	if root:
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ์—์„œ postOrder๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰
        postOrder(root.left)
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ์—์„œ postOrder๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰
        postOrder(root.right)
    	# ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
    	print(root.info, end=" ")
  • root ๋…ธ๋“œ๋ถ€ํ„ฐ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ๋กœ ๋‚ด๋ ค๊ฐ€๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณต
  • ๋”์ด์ƒ ํŒŒ๊ณ ๋“ค ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋กœ ๋‚ด๋ ค๊ฐ
  • ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
  • ์ด ๊ณผ์ •์„ ๋๊นŒ์ง€ ๋ฐ˜๋ณต

๐Ÿšข Levelorder

๐Ÿšฅ Root Node โ†’ left Node โ†’ right Node

  • ๊ฐ Level์˜ ๋…ธ๋“œ๋ฅผ ์™ผ์ชฝ๋ถ€ํ„ฐ ์ถœ๋ ฅ ํ›„, ๊ทธ ๋‹ค์Œ Level๋กœ ๋„˜์–ด๊ฐ€ ์ด ๊ณผ์ •์„ ๋ฐ˜๋ณต

๐Ÿ“‘ Code

from collections import deque

def levelOrder(root):
    if not root:
    	return 
    
    # deque ์ƒ์„ฑ
    queue = deque()
    # root ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€
    queue.append(root)
    # queue์— ์•„๋ฌด ๊ฒƒ๋„ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    while queue:
    	# queue์˜ ์ฒซ ๋ฒˆ์งธ ๊ฐ์ฒด๋ฅผ ์ถ”์ถœํ•˜์—ฌ ํ˜„์žฌ ๋…ธ๋“œ์— ํ• ๋‹น
        current_node = queue.popleft()
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅ
        print(current_node.info, end = ' ')
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด?
        if current_node.left: 
        	# queue์— ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€
            queue.append(current_node.left)
        # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด?
        if current_node.right: 
        	# queue์— ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€
            queue.append(current_node.right)
  • FIFO(First In First Out) ๋ฐฉ์‹์˜ Queue ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด collections ๋ชจ๋“ˆ์˜ deque์„ import
  • ์ƒ์œ„ Level๋ถ€ํ„ฐ ๋…ธ๋“œ๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ๋‹ด์„ queue๋ฅผ deque ์ž๋ฃŒ๊ตฌ์กฐ๋กœ ์„ ์–ธ
  • root ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ํ•ด๋‹น ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ์™€ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ queue์— ์Œ“์ด๊ฒŒ ๋จ.
  • ๋…ธ๋“œ ๋ฐ์ดํ„ฐ์˜ ์ถœ๋ ฅ์€ queue์—์„œ ์™ผ์ชฝ๋ถ€ํ„ฐ ๋ฝ‘ํ˜€ ๋‚˜์™€ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์œ„ Level๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์™ผ์ชฝ๋ถ€ํ„ฐ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅ๋˜๊ณ  ๊ทธ ๋‹ค์Œ Level๋กœ ๋„˜์–ด๊ฐ€์„œ ๋ฐ˜๋ณต๋˜๋Š” ํ˜•ํƒœ๋กœ ์ง„ํ–‰๋จ.

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