LALA's blog

[ 자료구조 ] 트리와 이진트리 본문

CS/자료구조

[ 자료구조 ] 트리와 이진트리

lala.seeun 2020. 4. 24. 17:23

트리의 기본적인 성질

- 노드가 N개인 트리는 항상 N-1개의 링크(link)를 가진다.
- 트리에서 루트에서 어떤 노드로 가는 경로는 유일하다.

- 또한 임의의 두 노드간의 경로도 유일하다. (같은 노드를 두 번 이상 방문하지 않는다는 조건하에).

이진 트리 (binary tree)란?

- 이진 트리는 여러 개의 자식 노드를 가질 수 있는 일반 트리와 다르게, 최대 2개의 자식만을 가질 수 있다.

- 즉, 0개, 1개, 2개의 자식 노드만 가질 수 있다.

- 각각의 자식 노드는 자신이 부모의 왼쪽 자식인지 오른쪽 자식인지가 지정된다. (자식이 한 명인 경우에도)

이진 트리 응용의 예

1) Expression Tree

 

2) 허프만 코드

각각의 알파벳에 부여된 이진 코드를 이런 트리의 형태로 표현할 수 있다.

 

 Full 이진 트리 VS Complete 이진 트리 

Full 이진 트리는 모든 레벨에서 노드들이 꽉 차있는 트리

Complete 이진 트리는 마지막 레벨을 제외한 레벨의 노드들이 모두 꽉 차있는 트리

 

Heap은 Complete 이진 트리이다.

높이가 h인 full Binary Tree는 2^h - 1개의 노드를 가진다.

노드가 N개인 Full or Complete 이진 트리의 높이는 O(longN)이다.

but, 노드가 N개인 일반 이진 트리의 높이는 최악의 경우에 N이 될 수 있다.

 

 이진 트리의 표현 

Complete 이진 트리의 경우 낮은 레벨의 왼쪽부터 차근차근 채워나가기 때문에 배열로 표현할 수 있다.

부모 노드의 배열 인덱스가 i일 때, 왼쪽 자식은 2 * i, 오른쪽 자식은 2 * i + 1로 표현 가능하다.



하지만 일반 이진 트리는 한 쪽으로만 편향된 모양이 나올 수 있어 규칙성이 성립하지 않기 때문에

연결 구조(Linked Structure)로 표현할 수 있다.

각 노드에 하나의 데이터 필드와 왼쪽 자식(left), 오른쪽 자식(right) 그리고 부모노드(p)의 주소를 저장한다.

(부모노드의 주소는 반드시 필요한 경우가 아니면 보통 생략 함)

 

 이진 트리의 순회 

순회 : 이진 트리의 모든 노드를 방문하는 일

트리는 연결 리스트나 배열처럼 선형 구조가 아니기 때문에, 순회할 때 더 다양한 방법이 있다.

 중순위(inorder) 순회 

이진 트리의 루트 노드를 R, 왼쪽 서브트리를 TL, 오른쪽 서브트리를 TR로 나누어 생각

① 먼저 TL을 inorder 순회하고

② R을 순회하고

③ TR을 순회한다.

 

INORDER-TREE-WALK( x ) 
      if x ≠ NIL
      then
              INORDER-TREE-WALK( left[x] )     // 왼쪽 자식
              print key[x]                                     // x의 데이터         
              INORDER-TREE-WALK( right[x] )   // 오른쪽 자식

Expression Tree

inorder 순회하면?

=> x + y * a + b / c

각 부트리를 순회할 때 괄호를 추가해주면 올바른 수식이 출력

=> ( x + y ) * ( ( a + b ) ) / c )

 선순위(preorder) 순회 

① 먼저 R을 순회하고

② TL을 순회하고

③ TR을 순회한다.

 

PREORDER-TREE-WALK( x )
      if x ≠ NIL then
      then
            print key[x]                                        // x의 데이터            
            PREORDER-TREE-WALK( left[x] )     // 왼쪽 자식
            PREORDER-TREE-WALK( right[x] )   // 오른쪽 자식

 후순위(postorder) 순회 

① 먼저 TL을 순회하고

② TR을 순회하고

③ R을 순회한다.

 

POSTORDER-TREE-WALK( x ) 
      if x ≠ NIL
      then           
            POSTORDER-TREE-WALK( left[x] )     // 왼쪽 자식
            POSTORDER-TREE-WALK( right[x] )   // 오른쪽 자식
            print key[x]                                          // x의 데이터  

postorder 순회하면?

=> x y + a b + c / *

 

연습) 설명해 보세요!

적혀있는 답은 중순위 순회

 Level-Order 순회 

레벨 순으로 방문하고, 동일 레벨에서는 왼->오른 순으로 순회한다.

큐(queue)를 이용하여 구현

1. 루트노드를 큐에 넣는다.

2. 큐에서 꺼내고(방문 했음) 자식 노드를 큐에 넣는다. 1을 반복한다.

 

LEVEL-ORDER-TREE-TRAVERSAL()
     visit the root;
     Q ← root;                  // Q is a queue
     while Q is not empty do
         v ← dequeue(Q);
         visit children of v;
         enqueue children of v into Q;
     end.
end.

방문순서: 3, 1, 5, 0 ,2, 4, 6, 7, 8

'CS > 자료구조' 카테고리의 다른 글

[ 자료구조 ] 싱글 링크드 리스트(Single Linked List)  (0) 2020.02.12