카테고리 없음

[자료구조/C언어] Binary Tree Traversal

2024. 6. 19. 00:02
목차
  1. 1. Traversal
  2. 2. Traversal의 종류
  3. 3. Tree Traversal의 응용
  4. 1.  directory size를 다 더해보자!
  5. 2.  Binary Expression Tree를 만들자!
  6. 3. Threaded Binary Tree
728x90

1. Traversal

  • 트리의 각 노드를 방문하는 과정이라 한다.
  • 특정 노드가 있는지 검색할 때 또는 삽입/삭제가 잘 되는지 확인하기 위해 사용된다.

 

2. Traversal의 종류

  • Inorder Traversal : LCR
    • 방문 순서 : a  left Subtree -> a root node -> a right subtree
    • Inorder Traversal
    • void Inorder(BTreeNode* root) {
      	if (root != NULL) {
          Inorder(root->left_child);
          printf("%d ", root->item);
          Inorder(root->right_child);
      }
  • Preorder Traversal : CLR
    • 방문 순서 : a root node -> a  left Subtree -> a right subtree
    • Preorder Traversal
    • void Preorder(BTreeNode* root) {
      	if (root != NULL) {
          	printf("%d ", root->item);
              Preorder(root->left_child);
              Preorder(root->right_child);
          }
      }
  • Postorder Traversal : LRC
    • 방문 순서 : a  left Subtree -> a right subtree -> a root node
    • Postorder Traversal
    • void Postorder(BTreeNode* root) {
      	if (root != NULL) {
          	Postorder(root->left_child);
              Postorder(root->right_child);
              printf("%d ", root->item);
          }
      }
  • Level order Traversal
    • 방문 순서 : Level 순서대로 방문한다.
    • queue를 사용한다.
      • 먼저 레벨 순으로 노드 하나를 삽입후, 노드가 Dequeue될 때 해당 Dequeue되는 노드의 자식 노드 2개를 EnQueue한다.
    • Level order
    • void Levelorder(BTreeNode* root) {
      	Queue queue;
          if (root == NULL) return;
          
          InitQueue(&queue);
          EnQueue(&queue, root);
          while (!IsEmpty(&queue)) {
          	root = Peek(&queue);
              Dequeue(&queue);
              
              printf("%d ", root->item);
              if (root->left_child != NULL) Enqueue(&queue, root->left_child);
              if (root->right_child != NULL) Enqueue(&queue, root->right_child);
          }
      }

 

3. Tree Traversal의 응용

1.  directory size를 다 더해보자!

  • 각각의 파일들은 다른 사이즈를 갖고 있고, 각 폴더는 10K의 사이즈를 갖는다.(다, 이진트리이다 보니 디렉토리 파일은 2개 밖에 못만든다.
  • post order 방식으로 구현하면 된다.
// Make use of postorder traversal.
int CalDirectorySize(BTreeNode* root) {
	int left_size, right_size;
    if (root == NULL) return 0;
    else {
    	left_size = CalDiretorySize(root->left_child);
        right_size = CalDirectorySize(root->right_child);
        return (root->item + left_size + right_size);
    }
}

 

2.  Binary Expression Tree를 만들자!

  • 우리는 Infix notation(Inorder)이라는 방식이 익숙하다.
    • 연산자가 피연산자 사이에 기록되는 방식(Ex. X + Y, (7+4) * 2 - 1 ...)
  • 수식 트리(Expression Tree)는 infix 표기법보다 이해하기 쉽다.
  •  
    Expression Tree
  • 따라서 우리는 다음과 같은 과정을 거쳐서 Expression Tree를 만들 예정이다.
  • Overall procedure


    • Infix notation -> Postfix notation 과정에서는 Stack을 사용하여 Postfix로 변환한다.
    • Postfix notation -> Expression tree 과정에서는 Stack을 사용하여 점증적으로 Tree를 만든다.(아래와 같이)

BTreeNode* MakeExpTree(char* exp, int len)	{	// exp : postfix로 주어진 표기법
	Stack stack;
    BTreeNode * node, *right_node, *left_node;
    
    InitStack(&stack);
    for (int i = 0; i < len; i++) {
    	// 숫자를 만나면 노드 생성, 연산자를 만나면 오른쪽에 들어갈 노드와 왼쪽에 들어갈 노드를 추출한다.
    	if ('0' <= exp[i] && exp[i] <= '9') node = CreateNode(exp[i]);
        else {
        	right_node = Peek(&stack), Pop(&stack);
            left_node = Peek(&stack), Pop(&stack);
            
            node = CreateNode(exp[i]);
            CreateRightSubtree(node, right_node);
            CreateLeftSubtree(node, left_node);
        }
        Push(&stack, node);
    }
    return Peek(&stack);
}
  • 아래의 예제와 같이 식을 Tree로 표현하면 Non-leaf node는 operator, leaf node는 operand로 구성되어 있는 것을 확인할 수 있다. 
  • 이제 위에서 만든 Expression Tree를 계산해보자. 계산하는 과정과 코드는 간단하다. 맨 왼쪽 아래에 있는 Subtree들을 계산하여 나온 값을 왼쪽 자식 노드로 저장한다. 이러한 과정을 반복하면 최종 결과를 얻을 수 있다.

 

 

int CalculateExpTree(BTreeNode* root) {
	int op1, op2;
   	if (root == NULL) return 0;
    if (root->left_child == NULL && root->right_child == NULL)	// Leaf Node=>피연산자=>반환
    	return root->item;
        
   	op1 = CalculateExpTree(root->left_child);	// left_child의 피연산자 저장
    op2 = CalculateExpTree(root->right_child);	// right_child의 피연산자 저장
    
    switch (root->item)
    {
    	case '+':	return op1 + op2;
        case '-':	return op1 - op2;
        case '*':	return op1 * op2;
        case '/':	return op1 / op2;
    }
    return 0;
}

 

3. Threaded Binary Tree

  • 스레드 이진 트리(Threaded binary tree)는 이진 트리의 한 종류로, 가리키는 곳이 없는 모든 오른쪽 널 포인터(null pointer)를 중위 후속자 노드로 연결하고, 가리키는 곳이 없는 모든 왼쪽 널 포인터를 중위 선행자 노드로 연결한 것이다.
  • 재귀적인 Inorder Traversal를 빠르게 할 수 있는 방법이다.
  • 순회 방법은 다음과 같다.
    • 가장 왼쪽 노드를 찾을 때까지 트리 이동한다.(실선 화살표는 왼쪽 이동을 의미)
    • Treaded link 또는 right-side 자식 포인터로 순회한다.(점선 화살표는 오른쪽 이동을 의미)

Threaded Binary Tree

#include <stdio.h>

typedef int BData;

typedef struct _bTreeNode
{
	BData item;
    struct _bTreeNode * left_child;
    struct _bTreeNode * right_child;
    bool isThreaded;
} BTreeNode;

BTreeNode* leftMost(BTreeNode* node)
{
	if (node == NULL) return NULL;
    while (node->left_child != NULL)
    	node = node->left_child;	// Go to the leftmost node.
    
    return node;
}

void inorder(BTreeNode* node)
{
	BTreeNode* cur = leftmost(node);
    while (cur != NULL) {
    	printf("%d ", cur->item);
    // If the node is a thread node, go to its inorder successor.
    if (cur->isThreaded)
    	cur = cur->right_child;
    else	// Go to the leftmost child in a right subtree.
    	cur = leftmost(cur->right_child);
    }
}

 

저작자표시 (새창열림)
  1. 1. Traversal
  2. 2. Traversal의 종류
  3. 3. Tree Traversal의 응용
  4. 1.  directory size를 다 더해보자!
  5. 2.  Binary Expression Tree를 만들자!
  6. 3. Threaded Binary Tree
JuniTech
JuniTech
프로그래밍을 정복하기 위한 좌충우돌 코린이의 기록
Juni IT Technology프로그래밍을 정복하기 위한 좌충우돌 코린이의 기록
JuniTech
Juni IT Technology
JuniTech
전체
오늘
어제
  • 분류 전체보기 (84)
    • Develop (29)
      • C, C++ (13)
      • Python (9)
      • Java (1)
      • JavaScript (0)
      • Arduino Uno (6)
    • CodingTest (38)
      • Baekjoon (36)
    • Project (0)
    • IT Issue (1)
    • Computer Science (11)
      • 프로그래밍 언어론 (3)
      • Open Source (3)
      • Data Structure (5)
    • Paper (0)
    • AI (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 🧑‍💻Github
  • 😎Juni의 잡동사니(일상 블로그)
  • 💰Juni의 투자일기(주식 블로그)

공지사항

인기 글

태그

  • LCD
  • 10810
  • c++
  • pygame
  • 10798
  • 10813
  • C
  • 파이썬
  • 프로그래밍어론
  • 11000
  • 10811
  • 구문법
  • Python
  • 문자열
  • 파스트리
  • 백준
  • 프로그래밍 역사
  • 2083번
  • Backjoon
  • 25206
  • 생존시간
  • 아두이노 우노
  • 10797
  • 프로그래밍 어론
  • 프어론
  • 27866
  • 포인터
  • 10812
  • 13241
  • 10988

최근 댓글

최근 글

hELLO · Designed By 정상우.
JuniTech
[자료구조/C언어] Binary Tree Traversal
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.