카테고리 없음

[자료구조] 트리 Tree

Seunghyun_KO 2022. 1. 15. 09:00
728x90
반응형

트리 (tree)

 - 원소들 간 1 : 多 관계를 가지는 비선형 자료구조

 - 원소들 간 계층 관계를 가지는 계층형 자료구조

 - 상위 원소에서 하위 원소로 내려가면서 확장되는 나무 모양의 구조

 ex)

출처 : IT COOKBOOK

 ☞ 노드 - 트리의 원소 : A, B, C, D, E, F, G, H, I, J, K, L

 ☞ 루트 노드 - 트리의 시작 노드 : A

 ☞ 간선 - 노드를 연결하는 선(= 부모 노드와 자식 노드를 연결하는 선)

 ☞ 형제 노드 - 같은 부모 노드의 자식 노드들 : (B, C, D), (E, F), (H, I, J), (K, L)

 ☞ 조상 노드 - 간선을 따라 루트 노드까지 이르는 경로에 있는 모든 노드들 : K의 조상 노드 = F, B, A

 ☞ 서브 트리 - 부모 노드와 연결된 간선을 끊었을 때 생성되는 트리 : 자식 노드의 개수만큼 서브 트리 생성

 ☞ 자손 노드 - 서브 트리에 있는 하위 레벨의 노드들 : B의 자손 노드 = E, F, K, L

 ☞ 차수

    ㄴ 노드의 차수 - 노드에 연결된 자식 노드의 수 : A의 차수 = 3, B의 차수 = 2, C의 차수 = 1

    ㄴ 트리의 차수 - 트리에 있는 노드의 차수 중 가장 큰 값 : 트리 A의 차수 = 3

    ㄴ 단말 노드(리프 노드) - 차수가 0인 노드(= 자식 노드가 없는 노드) : E, K, L, G, H, I, J

 ☞ 높이

    ㄴ 노드의 높이 - 루트에서 노드에 이르는 간선의 수(= 노드의 레벨) : B의 높이 = 1, F의 높이 = 2

    ㄴ 트리의 높이 - 트리에 있는 노드의 높이 중 가장 큰 값(= 최대 레벨) : 트리 A의 높이 = 3

 ☞ 포리스트 - 서브 트리의 집합

출처 : IT COOKBOOK


이진트리 (Binary Tree)

 - 트리의 노드 구조를 일정하게 정의하여 트리의 구현과 연산이 쉽도록 정의한 트리

 - 모든 노드는 왼쪽 자식 노드오른쪽 자식 노드만을 가짐

    ㄴ 부모 노드 : 자식 노드 수 = 1 : 2

    ㄴ 공백 노드도 자식 노드로 취급

    ㄴ 0 ≤ 노드의 차수 ≤ 2

 - 이진트리의 서브 트리도 이진트리

 - 특성

    ㄴ n개의 노드를 가진 이진트리는 항상 n-1개의 간선을 가진다.

    ㄴ 높이가 h인 이진트리가 가질 수 있는 노드의 최소 개수는 h+1개가 되며, 최대 개수는 2^(h+1) -1개가 된다.

 - 종류

    ① 포화 이진트리

> 모든 레벨에 노드가 포화상태로 차 있는 이진트리

 

> 높이가 h일 때, 최대의 노드 개수인 2^(h+1) -1개의 노드를 가진 이진트리

 

> 루트를 1번으로 하여 2^(h+1)-1까지 정해진 위치에 대한 노드 번호를 가진다.

 

 

② 완전 이진트리

 

 

> 높이가 h이고 노드 수가 n개일 때 (단, h+1 ≤ n ≤ 2^(h+1)) , 포화 이진트리의 노드 번호 1번부터 n번까지 빈 자가 없는 이진트리

 

 

 

 

③ 편향 이진트리

 > 높이 h에 대한 최소 개수의 노드를 가지면서 한쪽 방향의 자식 노드만을 가진 이진트리

 

> (좌) 왼쪽 편향 이진트리, (우) 오른쪽 편향 이진트리


순차 자료구조를 이용한 이진트리의 구현

 - 1차원 배열의 순차 자료구조 사용

    ㄴ 높이가 h인 포화 이진트리의 노드 번호를 배열의 인덱스로 사용

    ㄴ 인덱스 0번 : 실제로 사용하지 않고 비워둠

    ㄴ 인덱스 1번 : 루트 노드

노드 인덱스 성립 조건
노드 i의 부모 노드 ⌊ i / 2 ⌋ i > 1
노드 i의 왼쪽 자식 노드 2 X i (2 X i) n
노드 i의 오른쪽 자식 노드 (2 X i) + 1 (2 X i + 1) n
루트 노드 1 0 < n

단점

 - 편향 이진트리의 경우 사용하지 않는 배열 원소에 대한 메모리 공간 낭비 발생

 - 트리의 원소 삽입/삭제에 대한 배열 크기 변경 어려움


연결 자료구조를 이용한 이진트리의 구현

 - 연결 리스트를 사용하여 구현

 

[자료구조] 이중 연결 리스트

이중 연결 리스트(doubly linked list)  - 양쪽 방향으로 순회할 수 있도록 노드를 연결한 리스트  - 이중 연결 리스트의 노드 구조 ㄴ 두 개의 링크 필드와 한 개의 데이터 필드로 구성 ㄴ llink(left link

kwin0825.tistory.com

(좌) 완전 이진트리 / (우) 왼쪽 편향 이진 트리


이진트리의 순회(traversal)

 - 계층적 구조로 저장되어 있는 트리의 모든 노드를 방문하여 데이터를 처리하는 연산

    ㄴ 현재 노드를 방문하여 데이터를 읽는 작업

    ㄴ 현재 노드의 왼쪽 서브 트리로 이동하는 작업

    ㄴ 현재 노드의 오른쪽 서브 트리로 이동하는 작업

 - 이진트리가 순환적으로 정의되어 구성되어 있으므로, 순회 작업도 서브 트리에 대해서 순환적으로 반복하여 완성

 - 왼쪽 서브 트리에 대한 순회를 오른쪽 서브 트리보다 먼저 수행한다.

 - 순회의 종류

    ㄴ 전위 순회 : 노드 데이터 읽기 > 왼쪽 서브 트리 이동 > 오른쪽 서브 트리 이동

    ㄴ 중위 순회 : 왼쪽 서브 트리 이동 > 노드 데이터 읽기 > 오른쪽 서브 트리 이동

    ㄴ 후위 순회 : 왼쪽 서브 트리 이동 > 오른쪽 서브 트리 이동 > 노드 데이터 읽기

전위 순회(preorder traversal) >>> A - B - D - H - E - I - J - C - F - G - K

 - 노드 데이터 읽기 > 왼쪽 서브 트리 이동 > 오른쪽 서브 트리 이동

① 루트 A에서 시작하여 현재 노드 A의 데이터를 읽고, 왼쪽 서브 트리 B로 이동한다.
② 현재 노드 B의 데이터를 읽고, 왼쪽 서브 트리 D로 이동한다.
③ 현재 노드 D의 데이터를 읽는다.
④ 현재 노드 D의 왼쪽 단말 노드 H의 데이터를 읽고, 오른쪽 노드인 공백 노드를 읽는 것으로 노 드 D에 대한 순회가 끝난다. 이제 현재 노드 D의 이전 경로인 노드 B의 오른쪽 서브 트리 E로 이동한다.
⑤ 현재 노드 E의 데이터를 읽는다.
⑥ 현재 노드 E의 왼쪽 단말 노드 I의 데이터를 읽는다.
⑦ 현재 노드 E의 오른쪽 단말 노드 J의 데이터를 읽는 것으로 노드 E에 대한 순회가 끝나고, 이것으로 노드 E의 이전 경로인 노드 B의 오른쪽 서브 트리의 순회가 끝난다.
⑧ 현재 노드 C의 데이터를 읽는다.
⑨ 현재 노드 C의 왼쪽 단말 노드 F의 데이터를 읽고, 오른쪽 서브 트리 G로 이동한다.
⑩ 현재 노드 G의 데이터를 읽는다.
⑪ 공백 노드인 왼쪽 단말 노드를 읽고, 현재 노드 G의 오른쪽 단말 노드 K의 데이터를 읽는다.

중위 순회(inorder traversal) >>> H - D - B - I - E - J - A - F - C - G - K

 - 왼쪽 서브 트리 이동 > 노드 데이터 읽기 > 오른쪽 서브 트리 이동

① 루트 A에서 시작하여 노드 A의 왼쪽 서브 트리 B로 이동한다. 현재 노드 B의 왼쪽 서브 트리 D로 이동한다. 현재 노드 D의 왼쪽 단말 노드 H의 데이터를 읽는다.
② 현재 노드 D의 데이터를 읽고, 오른쪽 단말 노드인 공백 노드를 읽고 이전 경로인 노드 B로 돌아간다.
③ 현재 노드 B의 왼쪽 서브 트리 순회가 끝났으므로, 현재 노드 B의 데이터를 읽고, 오른쪽 서브 트리 E로 이동한다.
④ 현재 노드 E의 왼쪽 단말 노드 I의 데이터를 읽는다.
⑤ 현재 노드 E의 데이터를 읽는다.
⑥ 현재 노드 E의 오른쪽 단말 노드 J의 데이터를 읽고, 이전 경로인 노드 B로 이동한다.
⑦ 노드 B는 이미 방문했으므로 다시 이전 경로인 노드 A로 이동한다. 이로써 현재 노드 A의 왼쪽 서브 트리에 대한 순회가 끝났으므로 현재 노드 A의 데이터를 읽고, 오른쪽 서브 트리 C로 이동한다.
⑧ 현재 노드 C의 왼쪽 단말 노드 F의 데이터를 읽는다.
⑨ 현재 노드 C의 데이터를 읽고, 오른쪽 서브 트리 G로 이동한다.
⑩ 현재 노드 G의 왼쪽 단말 노드인 공백 노드를 읽고, 현재 노드 G의 데이터를 읽는다.
⑪ 현재 노드 G의 오른쪽 단말 노드 K의 데이터를 읽는다.

후위 순회(postorder traversal) >>> H - D - I - J - E - B - F - K - G - C - A

 - 왼쪽 서브 트리 이동 > 오른쪽 서브 트리 이동 > 노드 데이터 읽기

①루트 A에서 시작하여 노드 A의 왼쪽 서브 트리 B로 이동한다. 현재 노드 B에서 왼쪽 서브 트리 D로 이동한다. 현재 노드 D의 왼쪽 단말 노드 H의 데이터를 읽는다.
② 현재 노드 D의 오른쪽 단말 노드인 공백 노드를 읽는다. 현재 노드 D의 데이터를 읽고, 이전 경로 인 노드 B로 이동한다.
③ 현재 노드 B의 왼쪽 서브 트리에 대한 순회가 끝났으므로 현재 노드 B의 오른쪽 서브 트리 E로 이 동한다. 현재 노드 E의 왼쪽 단말 노드 I의 데이터를 읽는다.
④ 현재 노드 E의 오른쪽 단말 노드 J의 데이터를 읽는다.
⑤ 이제 현재 노드 E의 데이터를 읽고, 이전 경로인 노드 B로 이동한다.
⑥ 현재 노드 B의 오른쪽 서브 트리에 대한 순회가 끝났으므로, 현재 노드 B의 데이터를 읽고, 이전 경로인 노드 A로 이동한다.
⑦ 현재 노드 A의 왼쪽 서브 트리에 대한 순회가 끝났으므로, 오른쪽 서브 트리 C로 이동한다. 현재 노 드 C의 왼쪽 단말 노드 F의 데이터를 읽는다.
⑧ 현재 노드 C의 오른쪽 서브 트리 G로 이동한다. 현재 노드 G의 왼쪽 단말 노드인 공백 노드를 읽고, 오른쪽 단말 노드 K의 데이터를 읽는다.
⑨ 이제 현재 노드 G의 데이터를 읽고, 이전 경로인 노드 C로 이동한다.
⑩ 현재 노드 C의 오른쪽 서브 트리에 대한 순회가 끝났으므로, 현재 노드 C의 데이터를 읽고, 이전 경로인 노드 A로 이동한다.
⑪ 루트 노드 A에 대한 오른쪽 서브 트리에 대한 순회가 끝났으므로, 현재 노드 A의 데이터를 읽는다.

 

728x90
반응형