본문 바로가기

Python 문법 정복하기

[Python] Tree

트리는 이름처럼 계층형 구조로 위 아래가 구분되어 있습니다.

 

앞서 공부한 큐(Queue), 스택(Stack) 은 자료구조에서 선형 구조라고 하는데, 선형 구조란 자료를 구성하고 있는 데이터들이 순차적으로 나열시킨 형태를 의미합니다. 이와 달리 트리는 비선형 구조입니다. 비선형 구조는 데이터가 계층적 혹은 망으로 구성되어 있는데, 선형구조는 자료를 저장하고 꺼내는 것에 초점이 맞춰져 있고, 비선형구조는 표현에 초점이 맞춰져 있습니다.


 

Tree 에서 알아둘 용어 

 

 

  • Node: 트리에서 데이터를 저장하는 기본 요소
  • Root Node: 트리 맨 위에 있는 노드
  • Level: 최상위 노드를 Level 0으로 하였을 때, 하위 Branch로 연결된 노드의 깊이를 나타냄
  • Parent Node: 어떤 노드의 상위 레벨에 연결된 노드
  • Child Node: 어떤 노드의 하위 레벨에 연결된 노드
  • Leaf Node(Terminal Node): Child Node가 하나도 없는 노드
  • Sibling: 동일한 Parent Node를 가진 노드
  • Depth: 트리에서 Node가 가질 수 있는 최대 Level

 

이진 트리(Binary Tree)

 

각 노드가 최대 두 개의 자식을 가진다. 하위의 노드가 4~5개 일 수 없다. 무조건 0, 1, 2 개만 있어야 한다.

      o      Level 0 
    o o o    Level 1
   o  o  o   Level 2 # 이진 트리(X)

      o      Level 0 
    o   o    Level 1
   o o o     Level 2 # 이진 트리(O)

 

 

완전 이진 트리(Complete Binary Tree)

 

노드를 삽입할 때 최하단 왼쪽 노드부터 차례대로 삽입해야 한다.

      o      Level 0
    o   o    Level 1
     o o     Level 2  # -> 이진 트리 O 완전 이진 트리 X

      o      Level 0
    o   o    Level 1
   o o o     Level 2  # -> 이진 트리 O 완전 이진 트리 O

 

 

완전 이진 트리를 배열로 표현

 

트리 구조를 표현하는 방법은

직접 클래스를 구현해서 사용하는 방법완전 이진 트리를 사용한 배열로 표현하는 방법이 있다.

 

완전 이진 트리는 왼쪽부터 데이터가 쌓이기 때문에, 이를 순서대로 배열에 쌓으면서 표현할 수 있다.

트리를 구현할 때는 편의성을 위해 0번째 인덱스는 사용되지 않는다
그래서 None 값을 배열에 넣고 시작한다 [None]

      8      Level 0 -> [None, 8] 첫번째 레벨의 8을 넣고,
    6   3    Level 1 -> [None, 8, 6, 3] 다음 레벨인 6, 3을 넣고
   4 2 5     Level 2 -> [None, 8, 6, 3, 4, 2, 5] 다음 레벨인 4, 2, 5를 넣으면 된다!

그러면, [None, 8, 6, 3, 4, 2, 5] 라는 배열이 되는데
다시 역으로 이 배열을 활용해서 
다음과 같은 방법으로 트리 구조를 파악할 수 있다.

1. 현재 인덱스 * 2 -> 왼쪽 자식의 인덱스
2. 현재 인덱스 * 2 + 1 -> 오른쪽 자식의 인덱스
3. 현재 인덱스 // 2 -> 부모의 인덱스

예를 들어서 1번째 인덱스인 8의 왼쪽 자식은 6, 오른쪽 자식은 3
그러면 1 * 2 = 2번째 인덱스! 6!
그러면 1 * 2 + 1 = 3번째 인덱스! 3! 
부모를 찾아보면, 3 // 2 = 1번째 인덱스 8 이므로 부모를 찾을 수 있다.

이를 다시 생각해보면
[None, 8, 6, 3, 4, 2, 5] 는
8 밑에 6, 3 이 있고, 6, 3 밑에 4, 2, 5가 있는 완전 이진 트리!

 

 

완전 이진 트리의 높이

 

트리의 높이(Height)는, 루트 노드부터 가장 아래 리프 노드까지의 길이 이다!

예를 들어 다음과 같은 트리의 높이는 2라고 할 수 있다.

      o      Level 0  # 루트 노드
    o   o    Level 1
   o o o     Level 2  # 가장 아래 리프 노드

이 트리의 높이는 ? 2 - 0 = 2!

 

 

아래 예시를 보면,

레벨을 k라고 한다면 각 레벨에 최대로 들어갈 수 있는 노드의 개수는 2^k 개수 임을 알 수 있다.

      1            Level 0 -> 1개
    2   3          Level 1 -> 2개 
   4 5 6 7         Level 2 -> 4개
 8 9....... 14 15  Level 3 -> 8개 
                   Level k -> 2^k 개

 

 

높이가 h 인데 모든 노드가 꽉 차 있는 완전 이진 트리라면 모든 노드의 개수는 몇 개일까?
1 + 2^1 + 2^2 + 2^3 + 2^4 ..... 2^h

수식으로 표현하면 2^(h+1) - 1

 

높이가 h 일 때 최대 노드의 개수는 2^(h+1) -1개 이다.

이 때 최대 노드의 개수가 N이라면, h는 2^(h+1) -1 = N → h = log_2(N+1)-1 라고 할 수 있다.

 

즉, 완전 이진 트리 노드의 개수가 N일 때 최대 높이가 log_2(N+1) - 1 이므로

이진 트리의 높이는 최대 O(log(N)) 이다. 

'Python 문법 정복하기' 카테고리의 다른 글

[Python] Max Heap  (0) 2024.04.14
[Python] HashTable (Chaining, Open Addressing)  (0) 2024.03.24
[Python] LinkedList 예제 (Palindrome)  (0) 2024.03.23
[Python] Queue 예제 (Josephus)  (0) 2024.03.23
[Python] Queue (FIFO)  (0) 2024.03.23