Posts [개발자 블로그] Tree(트리)
Post
Cancel

[개발자 블로그] Tree(트리)

트리란?

  • 계층적인 자료를 표현하기 위한 자료구조
  • 데이터 요소들의 단순한 나열이 아닌 부모-자식 관계의 계층적 구조로 표현
  • 트리는 그래프의 한 종류이며 사이클이 없다.
  • 실제 나무를 거꾸로 한 것과 같은 모양을 하고 있기 때문에 트리라고 부른다.

2

  • node: 트리를 구성하고 있는 각 요소
  • Edge(간선): 트리를 구성하기 위해 노드와 노드를 연결하는 선
  • RootNode: 최상위 계층에 존재하는 노드
  • level: 트리의 특정 깊이를 가지는 노드의 집합
  • degree:(차수): 하위 트리 개수 / 간선 수(degree) = 각 노드가 가진 가지의 수
  • Terminal Node ( = Leaf Node, 단말 노드) : 하위에 다른 노드가 연결되어 있지 않은 노드
  • Internal Node (내부노드, 비단말 노드) : 단말 노드를 제외한 모든 노드로 루트 노드를 포함한다.

트리의 특징

  • 그래프의 한 종류이며 ‘최소 연결 트리’ 라고도 불린다.
  • 트리는 계층 모델이다.
  • 트리는 DAG(Directed Acyclic Graphs, 방향성이 있는 비순환 그래프)의 한 종류이다.
    • loop나 circuit이 없다. 당연히 self-loop도 없다.
    • 즉, 사이클이 없다.
  • 즉 노드가 N개인 트리는 항상 N-1개의 간선(edge)을 가진다.
    • 즉, 간선은 항상 (정점의 개수 - 1) 만큼을 가진다.
  • 루트에서 어떤 노드로 가는 경로는 유일하다.
    • 임의의 두 노드 간의 경로도 유일하다. 즉, 두 개의 정점 사이에 반드시 1개의 경로만을 가진다.
  • 한 개의 루트 노드만이 존재하며 모든 자식 노드는 한개의 부모 노드만을 가진다.
    • 부모-자식 관계이므로 흐름은 top-bottom 아니면 bottom-top으로 이루어진다.
  • 순회는 Pre-order(전위순회), In-order(중위순회)아니면 Post-order(후위순회)로 이루어진다. 이 3가지 모두 DFS/BFS안에 있다.
  • 트리는 이진트리, 이진 탐색 트리, 균형트리(AVL 트리, red-black 트리), 이진 힙(최대힙, 최소힙) 등이 있다.

트리의 종류

트리의 구현 방법

  • 기본적으로 트리는 그래프의 한 종류이므로 그래프의 구현 방법(리스트 또는 배열)으로 구현할 수 있다.

배열 이용

  • 1) 1차원 배열에 자신의 부모 노드만 저장하는 방법
    • 트리는 부모 노드를 0개 또는 1개를 가지기 때문
    • 루트노드는 부모 노드가 자기 자신
  • 2) 1차원 배열에 트리구조상의 위치에 해당하는 값을 저장하는 방법
    • 스크린샷 2021-04-22 오후 4 03 38
  • 3) 이진 트리의 경우, 2차원 배열에 자식 노드를 저장하는 방법
    • 이진 트리는 각 노드가 최대 두 개의 자식을 갖는 트리이기 때문
    • Ex) A[i][0]: 왼쪽 자식 노드, A[i][1]: 오른쪽 자식 노드

배열의 단점

  • 빈 노드에 대해서는 계속 사용하지 않기 때문에 메모리 낭비
  • 데이터의 삽입, 삭제 연산시 노드의 레벨 변경으로 인한 데이터의 이동 발생

연결리스트를 이용

  • 각 노드는 data필드와 왼쪽 서브 트리를 가리키는 필드, 오른쪽 서브 트리를 가리키는 필드로 구성

이진 트리의 순회

스크린샷 2021-04-22 오후 4 10 05

  • 중위 순회(inorder traversal)
    • 왼쪽 서브트리 -> 루트 -> 오른쪽 서브트리
    • 루트 노드가 가운데에 온다.
    • 4-2-5-1-3
    1
    2
    3
    4
    5
    6
    7
    
      void inOrderTraversal(TreeNode node) {
          if(node != null) {
              inOrderTraversal(node.left);
              visit(node);
              inOrderTraversal(node.right);
          }
      }
    
  • 후위 순회(postorder traversal)
    • 왼쪽 서브트리 -> 오른쪽 서브트리 -> 루트
    • 루트 노드가 후위에 온다.
    • 4-5-2-3-1
    1
    2
    3
    4
    5
    6
    7
    
      void postOrderTraversal(TreeNode node) {
          if(node != null) {
              postOrderTraversal(node.left);
              postOrderTraversal(node.right);
              visit(node);
          }
      }
    
  • 전위 순회(preorder traversal)
    • 루트 -> 왼쪽 -> 오른쪽
    • 루트 노드가 맨 앞에 온다.
    • 1-2-4-5-3
    1
    2
    3
    4
    5
    6
    7
    
      void preOrderTraversal(TreeNode node) {
          if(node != null) {
              visit(node);
              preOrderTraversal(node.left);
              preOrderTraversal(node.right);
          }
      }
    

출처

This post is licensed under CC BY 4.0 by the author.

[개발자 블로그] Binary Tree(이진트리)

[개발자 블로그] red-black 트리 & AVL 트리