Computer Science/Data Structures

๐ŸŒณ Binary Tree ๐ŸŒณ

metamong 2023. 12. 19.

(left) binary tree / (right) binary search tree

theory

๐ŸŒณ ๊ฐ€๊ณ„๋„์™€ ๊ฐ™์€ ๊ณ„์ธต์ ์ธ ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ

: Binary Tree is defined as a tree data structure where each node has at most 2 children. Since each element in a binary tree can have only 2 children, we typically name them the left and right child.

 

๐ŸŒณ ํŠธ๋ฆฌ ๊ด€๋ จ ์šฉ์–ด

โ‘  root node: ๋ถ€๋ชจ๊ฐ€ ์—†๋Š” ์ตœ์ƒ์œ„ ๋…ธ๋“œ

โ‘ก leaf node: ์ž์‹์ด ์—†๋Š” ๋…ธ๋“œ

โ‘ข size: ํŠธ๋ฆฌ์— ํฌํ•จ๋œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜

โ‘ฃ depth: ํŠน์ • ๋…ธ๋“œ์—์„œ ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ(์ฆ‰ ์œ„ 1๋ฒˆ ๋…ธ๋“œ์˜ ๊นŠ์ด๋Š” 0, 2๋ฒˆ ๋…ธ๋“œ์˜ ๊นŠ์ด๋Š” 1)

โ‘ค height: ๊นŠ์ด ์ค‘ ์ตœ๋Œ“๊ฐ’(์œ„ 8๋ฒˆ ๋…ธ๋“œ์˜ ๊นŠ์ด๊ฐ€ height)

โ‘ฅ degree: ๊ฐ ๋…ธ๋“œ์˜ (์ž์‹ ๋ฐฉํ–ฅ) ๊ฐ„์„  ๊ฐœ์ˆ˜(์ฆ‰ ์ž์‹์˜ ๊ฐœ์ˆ˜) (์œ„ 1๋ฒˆ ๋…ธ๋“œ์˜ ์ฐจ์ˆ˜๋Š” 2)

 

๐ŸŒณ ๊ธฐ๋ณธ์ ์œผ๋กœ ํŠธ๋ฆฌ์˜ ํฌ๊ธฐ๊ฐ€ N์ผ ๋•Œ, ์ „์ฒด ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜๋Š” N-1๊ฐœ

binary search tree

๐ŸŒณ binary tree ์ค‘์—์„œ ์ด์ง„ ํƒ์ƒ‰์ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ ์•ˆ๋œ ํšจ์œจ์ ์ธ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์˜ ์ผ์ข…

 

๐ŸŒณ ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ < ๋ถ€๋ชจ ๋…ธ๋“œ < ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ

 

๐ŸŒณ The left and right subtree each must also be a binary search tree. There must be no duplicate nodes.

basis of comparison binary tree binary search tree
definition a nonlinear data structure where each node can have at most two child nodes.  a node based binary tree that further has right and left subtree that too are binary search tree.
types Full binary tree
Complete binary tree
Extended Binary tree and more
AVL tree
Splay tree
T-trees and more
structure In BINARY TREE there is no ordering in terms of how the nodes are arranged In BINARY SEARCH TREE the left subtree has elements less than the nodes element and the right subtree has elements greater than the nodes element.
data representation Data Representation is carried out in a hierarchical format. Data Representation is carried out in the ordered format.
duplicate values Binary trees allow duplicate values. Binary Search Tree does not allow duplicate values.
speed The speed of deletion, insertion, and searching operations in Binary Tree is slower as compared to Binary Search Tree because it is unordered Because the Binary Search Tree has ordered properties, it conducts element deletion, insertion, and searching faster.
complexity Time complexity is usually O(n). Time complexity is usually O(logn).
application It is used for retrieval of fast and quick information and data lookup. It works well at element deletion, insertion, and searching.
usage It serves as the foundation for implementing Full Binary Tree, BSTs, Perfect Binary Tree, and others.  It is utilized in the implementation of Balanced Binary Search Trees such as AVL Trees, Red Black Trees, and so on.

 

๐ŸŒณ binary searching example

๐ŸŒณ binary search tree๊ฐ€ ์ด๋ฏธ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์กฐํšŒํ•˜์ž. ์ฐพ๊ณ ์ž ํ•˜๋Š” ์›์†Œ๊ฐ€ 37์ด๋ผ ๊ฐ€์ •ํ•˜๋ฉด, root node๋ถ€ํ„ฐ ๋ฐฉ๋ฌธํ•ด์„œ ํƒ์ƒ‰ ์ง„ํ–‰. ํ˜„์žฌ node ๊ฐ’์€ 30์ด๋ฏ€๋กœ ์ฐพ๋Š” ์›์†Œ๊ฐ€ ๊ฐ’์ด ๋” ํผ. ๋”ฐ๋ผ์„œ ํ˜„์žฌ root node์—์„œ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋ฐฉ๋ฌธ. ๊ทธ ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ๋Š” ๊ฐ’์ด 48์ธ node ๋ฐฉ๋ฌธ(์ฆ‰ root node์˜ ์™ผ์ชฝ ๋ฒ”์œ„๋Š” ๋ฐฉ๋ฌธํ•  ํ•„์š” ์—†์Œ - ํƒ์ƒ‰ ๋ฒ”์œ„ ์ ˆ๋ฐ˜์œผ๋กœ ์ค„์–ด๋“ฆ). 37์€ 48๋ณด๋‹ค ์ž‘์œผ๋ฏ€๋กœ ์™ผ์ชฝ ๋ฐฉ๋ฌธ. 37 ํ™•์ธ! ์›์†Œ๋ฅผ ์ฐพ์•˜์œผ๋ฏ€๋กœ ํƒ์ƒ‰ ์ข…๋ฃŒ

 

๐ŸŒณ ์ฆ‰ ์ด์ง„ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ๋” ๊ณ ์•ˆ๋œ ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ. ์ด์ƒ์ ์ธ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ํƒ์ƒ‰ O(logn). ํ•˜์ง€๋งŒ ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ tree๊ฐ€ ๊ท ํ˜•์ด ์žกํ˜€์žˆ์„ ๊ฒฝ์šฐ๋งŒ ๊ฐ€๋Šฅํ•œ ์‹œ๊ฐ„ ๋ณต์žก๋„. ๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ๋Š” ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ ์กด์žฌ

traversal(ํŠธ๋ฆฌ์˜ ์ˆœํšŒ)

๐ŸŒณ ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ์— ํฌํ•จ๋œ ๋…ธ๋“œ๋ฅผ ํŠน์ •ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•œ ๋ฒˆ์”ฉ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ๋ฒ•. ํŠธ๋ฆฌ์˜ ์ •๋ณด๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ™•์ธ ๊ฐ€๋Šฅ

 

โ‘  ์ „์œ„ ์ˆœํšŒ(pre-order traverse): ๋ฃจํŠธ๋ฅผ ๋จผ์ € ๋ฐฉ๋ฌธ

โ‘ก ์ค‘์œ„ ์ˆœํšŒ(in-order traverse): ์™ผ์ชฝ ์ž์‹์„ ๋ฐฉ๋ฌธํ•œ ๋’ค์— ๋ฃจํŠธ๋ฅผ ๋ฐฉ๋ฌธ

โ‘ข ํ›„์œ„ ์ˆœํšŒ(post-order traverse): ์˜ค๋ฅธ์ชฝ ์ž์‹์„ ๋ฐฉ๋ฌธํ•œ ๋’ค์— ๋ฃจํŠธ๋ฅผ ๋ฐฉ๋ฌธ

 

ex)

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

: ๋ฃจํŠธ๋ฅผ ๋จผ์ € ์ถœ๋ ฅ(A)ํ›„ ์™ผ์ชฝ ๋“ค์–ด๊ฐ€์„œ ์ถœ๋ ฅ(B) ๊ทธ ๋‹ค์Œ ์™ผ์ชฝ(D)์ถœ๋ ฅ. ์ด์ œ ์ž์‹ ๋…ธ๋“œ ์—†์œผ๋ฉด ๋‹ค์‹œ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ ์˜ค๋ฅธ์ชฝ(E) ์ถœ๋ ฅ. ๋‹ค์‹œ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ ์˜ค๋ฅธ์ชฝ(C) ์ถœ๋ ฅ. ๊ทธ ๋‹ค์Œ ์™ผ์ชฝ(F) ์ถœ๋ ฅ. ์ž์‹ ๋…ธ๋“œ ์—†์œผ๋ฏ€๋กœ ๋‹ค์‹œ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ ์˜ค๋ฅธ์ชฝ(G) ์ถœ๋ ฅ

 

A → B  → D → E → C → F → G

 

โ‘ก ์ค‘์œ„ ์ˆœํšŒ(์•„๋ž˜๋กœ ์ญ‰ ๋‚ด๋ ค๊ฐ€์„œ ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ๋ถ€ํ„ฐ ์ถœ๋ ฅ)

: ๋ฃจํŠธ์—์„œ ์‹œ์ž‘ํ•ด ๋งจ ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ(D)๋กœ ์ด๋™. ๋‹ค์‹œ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ ๋…ธ๋“œ(B) ์ถœ๋ ฅ. ์˜ค๋ฅธ์ชฝ(E) ์ถœ๋ ฅ. ๋‹ค์‹œ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ A ์ถœ๋ ฅ. ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ C ์ถœ๋ ฅ. ์™ผ์ชฝ๋ถ€ํ„ฐ F ์ถœ๋ ฅ. ๋งˆ์ง€๋ง‰ G ์ถœ๋ ฅ

 

D → B → E → A → F → C → G

 

โ‘ข ํ›„์œ„ ์ˆœํšŒ

: ๋ฃจํŠธ์—์„œ ์‹œ์ž‘ํ•ด ๋งจ ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ(D)๋กœ ์ด๋™. ๊ทธ ๋‹ค์Œ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ ๋‹ค๋ฅธ ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ(E) ์ถœ๋ ฅ. ์ด์ œ ์ƒ์œ„ ๋…ธ๋“œ B ์ถœ๋ ฅํ•˜๋Š” ๋ฐฉ์‹

 

D → E → B → F → G → C → A

 

โ˜† ์ฆ‰ ์ „์œ„ ์ˆœํšŒ๋Š” ๋ฃจํŠธ ๋จผ์ € / ์ค‘์œ„ ์ˆœํšŒ๋Š” ์™ผ์ชฝ ๋จผ์ € →  ๋ฃจํŠธ →  ์˜ค๋ฅธ์ชฝ / ํ›„์œ„ ์ˆœํšŒ๋Š” ์™ผ์ชฝ →  ์˜ค๋ฅธ์ชฝ →  ๋ฃจํŠธโ˜†

traversal ๊ตฌํ˜„ ์˜ˆ์ œ

โ˜† pre-order๋Š” upper - left -right / in-order๋Š” left - upper - right / post-order๋Š” left - right - upper โ˜†

class Node:
    def __init__(self, data, left_node, right_node):
        self.data = data
        self.left_node = left_node
        self.right_node = right_node

#preorder traversal
def pre_order(node):#upper -> left -> right
    print(node.data, end=' ') #upper print: when visited, just print right away
    if node.left_node != None: #left first(recursive)
        pre_order(tree[node.left_node])
    if node.right_node != None:
        pre_order(tree[node.right_node])

#inorder traversal
def in_order(node):#left -> upper -> right
    if node.left_node != None: #if left_node, search 
        in_order(tree[node.left_node])
    print(node.data, end= ' ') #if left_node doesn't exist, print upper-node
    if node.right_node != None:
        in_order(tree[node.right_node])

#postorder traversal
def post_order(node): #left -> right -> upper
    if node.left_node != None:
        post_order(tree[node.left_node])
    if node.right_node != None:
        post_order(tree[node.right_node])   
    print(node.data, end= ' ')

n=int(input())
tree={}

for i in range(n):
    data, left_node, right_node = input().split()
    if left_node == 'None':
        left_node = None
    if right_node == 'None':
        right_node = None
    
    tree[data] = Node(data, left_node, right_node)

pre_order(tree['A']) #starts from A node
print()
in_order(tree['A'])
print()
post_order(tree['A'])


#input
'''
7
A B C
B D E
C F G
D None None
E None None
F None None
G None None
'''

#output
'''
A B D E C F G
D B E A F C G
D E B F G C A
'''

์ด์ฝ”ํ…Œ 2021

geeksforgeeks

 

'Computer Science > Data Structures' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๐ŸฅชArray & Linked List  (2) 2024.01.08
set() & dict() - ์ง‘ํ•ฉ๊ณผ ๋งต  (0) 2023.08.03
Binary heap  (0) 2023.02.06
Types of Binary Tree๐ŸŒฒ  (0) 2023.01.10
priority queue(binary heap)  (0) 2023.01.09

๋Œ“๊ธ€