C언어 이진 트리 (Binary Tree)

코딩C언어
읽는데 10분 소요
처음 쓰여진 날: 2026-04-24
마지막 수정일: 2026-04-24
조회수:

요약

C언어 이진 트리의 노드 구조체 정의와 전위/중위/후위 재귀 순회를 알아봅니다. 자료구조와 재귀를 함께 다루는 정보처리기사 실기 대비 핵심 개념을 정리합니다.

이진 트리 핵심 정리

개념설명예시
이진 트리각 노드가 최대 2개의 자식(left, right)을 가지는 트리부모 → 왼쪽/오른쪽 자식
노드(Node)데이터 + 두 자식 포인터를 가진 구조체int data, Node* left, Node* right
루트(root)트리의 시작 노드 (부모 없음)트리의 가장 위 노드
리프(leaf)자식이 없는 노드left == NULL && right == NULL
전위 순회Root → Left → Right부모를 먼저 방문
중위 순회Left → Root → Right왼쪽부터 차례로
후위 순회Left → Right → Root부모를 마지막에 방문

이진 트리란? 쌩기초

이진 트리 (Binary Tree)는 각 노드가 최대 2개의 자식 노드(왼쪽, 오른쪽)를 가지는 자료구조입니다.

연결 리스트는 한 노드가 다음 노드 하나만 가리키지만, 이진 트리는 두 개의 노드를 가리킵니다. 구조체포인터를 함께 사용하므로 두 개념이 익숙하지 않다면 먼저 읽고 돌아오세요.

이진 트리 기본 구조
루트 노드 1을 시작으로 각 노드가 최대 2개의 자식(left, right)을 가지는 이진 트리. 자식이 없는 노드(4, 5, 6)는 리프 노드입니다.
용어의미그림 예시
루트(root)트리의 가장 위 노드1
부모(parent)자식을 가진 노드2는 4, 5의 부모
자식(child)부모 아래 노드4, 5는 2의 자식
리프(leaf)자식이 없는 노드4, 5, 6

노드 구조체 정의 쌩기초

이진 트리의 노드는 데이터 + 왼쪽 자식 포인터 + 오른쪽 자식 포인터 3개의 멤버를 가집니다.

c
코드 하이라이팅 중...

struct Node* leftstruct Node* right는 자기 자신과 같은 타입(struct Node)을 가리키는 포인터입니다. 이렇게 자기 자신과 같은 타입의 포인터를 멤버로 가지는 것을 자기참조 구조체라고 합니다.

노드 구조체 메모리 박스
노드 한 개는 데이터 한 칸(int data)과 왼쪽·오른쪽 자식의 주소 두 칸(struct Node* left, struct Node* right)으로 구성됩니다.

노드 만들기 (정적 선언)

가장 단순한 방법은 노드를 변수로 선언하고 직접 연결하는 것입니다. 위 그림(루트 1, 자식 2/3, 2의 자식 4/5, 3의 오른쪽 자식 6)을 코드로 만들면 다음과 같습니다.

c
코드 하이라이팅 중...

구조체 초기화(중괄호 {...}로 멤버 값을 한 번에 채우는 것) 순서는 멤버 선언 순서(data, left, right)와 일치해야 합니다. 자식이 없으면 NULL을 넣어 "여기 아래로 더 이상 자식 노드가 없다"는 표시를 합니다.

정적 선언 노드들의 메모리 배치와 연결
각 노드 변수(n1~n6)가 메모리에 따로 존재하고, left/right에 다른 노드의 주소(예: &n4 = 주소400)를 저장하여 트리로 연결됩니다.

노드 만들기 (동적 할당)

정적 선언은 개념 이해용으로 살펴봤고, 이제부터는 실기에서 자주 쓰는 동적 할당 방식을 배웁니다. 두 방식 모두 위와 똑같은 트리를 만들며, 실기에서는 동적 할당이 표준입니다. malloc으로 동적 할당해 노드를 만드는 패턴을 숙지해 두세요.

c
코드 하이라이팅 중...

malloc은 노드 크기만큼 메모리를 할당하고 그 시작 주소를 반환합니다. 반환값을 struct Node*형변환한 뒤 멤버를 초기화합니다.

c
코드 하이라이팅 중...

위 정적 선언과 똑같은 트리(루트 1, 자식 2/3, 2의 자식 4/5, 3의 오른쪽 자식 6)가 만들어집니다.

화살표 연산자 ->는 포인터가 가리키는 구조체의 멤버에 접근합니다. root->left->left는 "root의 왼쪽 자식의 왼쪽 자식"을 의미합니다.

malloc으로 동적 할당된 노드들의 메모리 배치
createNode를 호출할 때마다 malloc이 새 노드를 메모리에 만들고 그 주소를 반환합니다. root 변수는 첫 번째 노드(data=1)의 주소를 가리킵니다.

트리 순회 기초

순회(Traversal)는 트리의 모든 노드를 한 번씩 방문하는 것입니다. 여기서 "방문"이란 그 노드의 데이터를 출력하거나 처리하는 것을 말합니다. 이진 트리에서는 부모와 두 자식의 방문 순서에 따라 전위·중위·후위 3가지 순회가 있습니다.

순회방문 순서영문
전위 순회Root → Left → Rightpreorder
중위 순회Left → Root → Rightinorder
후위 순회Left → Right → Rootpostorder

각 순회는 재귀함수로 구현하며, 기저 조건(재귀를 멈추는 종료 지점)은 root == NULL 입니다. 리프 노드의 leftright(NULL)를 따라간 직후 preorder(NULL)이 호출되는 순간 즉시 return합니다.

전위 순회 (preorder) 기초

부모(Root)를 먼저 방문하고, 왼쪽 자식, 오른쪽 자식 순서로 재귀 호출합니다.

c
코드 하이라이팅 중...

위 트리(루트=1)에서 preorder(root)를 호출하면 다음 순서로 노드를 방문합니다.

text
코드 하이라이팅 중...
전위 순회 방문 순서
루트 1부터 시작해 부모 → 왼쪽 → 오른쪽 순으로 내려가며 방문합니다. 번호는 출력 순서입니다.

중위 순회 (inorder) 기초

왼쪽 자식을 먼저 끝까지 방문한 뒤 부모를 방문하고, 마지막으로 오른쪽 자식을 방문합니다.

c
코드 하이라이팅 중...

같은 트리에서 inorder(root) 호출 결과는 다음과 같습니다.

text
코드 하이라이팅 중...
중위 순회 방문 순서
가장 왼쪽 노드(4)부터 시작해 왼쪽 → 부모 → 오른쪽 순으로 방문합니다. 번호는 출력 순서입니다.

후위 순회 (postorder) 기초

왼쪽 자식과 오른쪽 자식을 모두 방문한 뒤 부모를 마지막으로 방문합니다.

c
코드 하이라이팅 중...

같은 트리에서 postorder(root) 호출 결과는 다음과 같습니다.

text
코드 하이라이팅 중...
후위 순회 방문 순서
자식들을 모두 방문한 뒤 부모를 마지막에 방문합니다. 루트 1이 가장 마지막에 출력됩니다. 번호는 출력 순서입니다.

재귀 호출 추적하기 심화

순회 결과만 외우지 말고, 재귀 호출이 어떻게 펼쳐지는지 직접 따라가 봅시다. 전위 순회를 예로 듭니다.

c
코드 하이라이팅 중...

함수 호출이 기저 조건(NULL)에 도달할 때까지 펼쳐집니다. 기저 조건에 도달하면 자기를 호출한 함수로 돌아가 다음 줄을 실행합니다.

text
코드 하이라이팅 중...

들여쓰기 트리를 위에서 아래로 읽으면 함수가 실제로 실행되는 시간 순서와 같습니다(재귀가 깊이 우선으로 펼쳐지기 때문입니다). 들여쓰기 1칸은 함수 호출 1단계 깊이를 나타냅니다. 각 호출에서 printf가 실행되는 시점을 위에서 아래로 읽으면 출력 순서가 그대로 나옵니다: 1 2 4 5 3 6.

전위 순회 재귀 호출 추적
재귀 호출이 깊이 우선으로 펼쳐지다가 기저(NULL)에 도달하면 위로 복귀합니다. 들여쓰기 1칸이 호출 깊이 1단계이며, 각 단계에서 printf가 누적되어 최종 출력 1 2 4 5 3 6이 됩니다.

순회별 출력 비교

같은 트리를 세 가지 순회로 출력한 결과를 비교하면 차이가 한눈에 보입니다.

순회출력 순서첫 출력마지막 출력
전위(preorder)1 2 4 5 3 6루트(1)가장 오른쪽 리프(6)
중위(inorder)4 2 5 1 3 6가장 왼쪽 리프(4)가장 오른쪽 리프(6)
후위(postorder)4 5 2 6 3 1가장 왼쪽 리프(4)루트(1)

정보처리기사 실기 대비 문제

관련 글

(41개)
제목태그시험
C언어 형변환 (Casting)
C언어
-
C언어 연결 리스트 뒤집기 (Reverse Linked List)
C언어
-
C언어 사용자 정의 함수 기초
C언어
-
C언어 이진 트리 (Binary Tree) | 정처기 감자