이 내용은 윤성우의 열혈 자료구조를 학습한 내용입니다.
트리는 계층적 관계(Hierarchical Reelationship)를 표현하는 자료구조다.
자료구조는 근본적으로 무엇인가를 ‘표현’하는 도구이다.

트리 구조상 위에 있을수록 촌수가 높다.

위 그림과 같이 큰 트리는 작은 트리로 구성이 된다.





이진 트리는 재귀적인 특성을 지니고 있다. (서브트리의 서브트리)


#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
typedef int BTData;
typedef struct _bTreeNode // 이진 트리의 노드를 표현한 구조체
{
BTData data;
struct _bTreeNode * left;
struct _bTreeNode * right;
} BTreeNode;
BTreeNode * MakeBTreeNode(void);
BTData GetData(BTreeNode * bt);
void SetData(BTreeNode * bt, BTData data);
BTreeNode * GetLeftSubTree(BTreeNode * bt);
BTreeNode * GetRightSubTree(BTreeNode * bt);
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub);
void MakeRightSubTree(BTreeNode * main, BTreeNode * sub);
#endif
이진 트리의 모든 노드는 직/간접적으로 연결되어 있다.
따라서 루트 노드의 주소 값만 기억하면, 이진트리 전체를 가리키는것과 다름이 없다.
BTreeNode * MakeBTreeNode(void);: 노드의 생성 
left와 right는 NULL로 자동 초기화 된다.BTData GetData(BTreeNode * bt);: 노드에 저장된 데이터를 반환void SetData(BTreeNode * bt, BTData data);: 노드에 데이터를 저장BTreeNode * GetLeftSubTree(BTreeNode * bt);: 왼쪽 서브 트리(노드) 주소 값 반환BTreeNode * GetRightSubTree(BTreeNode * bt);: 오른쪽 서브 트리(노드) 주소 값 반환sub 로 전달된 트리 또는 노드를 매개변수 main 으로 전달된 노드에 연결한다.void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub);: 왼쪽 서브트리를 연결한다.void MakeRightSubTree(BTreeNode * main, BTreeNode * sub);: 오른쪽 서브 트리를 연결한다.BTreeNode * MakeBTreeNode(void);: 노드의 생성 후 그 주소 값을 반환BTreeNode * MakeBTreeNode(void)
{
BTreeNode * nd = (BTreeNode*)malloc(sizeof(BTreeNode));
nd->left = NULL;
nd->right = NULL;
return nd;
}BTData GetData(BTreeNode * bt);: 노드에 저장된 데이터를 반환BTData GetData(BTreeNode * bt)
{
return bt->data;
}void SetData(BTreeNode * bt, BTData data);: 노드에 데이터를 저장void SetData(BTreeNode * bt, BTData data)
{
bt->data = data;
}BTreeNode * GetLeftSubTree(BTreeNode * bt);: 왼쪽 서브 트리(노드) 주소 값 반환BTreeNode * GetLeftSubTree(BTreeNode * bt)
{
return bt->left;
}BTreeNode * GetRightSubTree(BTreeNode * bt);: 오른쪽 서브 트리(노드) 주소 값 반환BTreeNode * GetRightSubTree(BTreeNode * bt)
{
return bt->right;
}서브 트리의 연결
왼쪽 또는 오른쪽 서브 트리가 존재한다면, 해당 트리를 삭제하고서 새로운 왼쪽 또는 오른쪽 서브 트리를 연결한다.
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub);: 왼쪽 서브트리 연결void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub)
{
if(main->left != NULL)
free(main->left);
main->left = sub;
}void MakeRightSubTree(BTreeNode * main, BTreeNode * sub);: 오른쪽 서브 트리 연결 void MakeRightSubTree(BTreeNode * main, BTreeNode * sub)
{
if(main->right != NULL)
free(main->right);
main->right = sub;
}free 함수를 호출해야 한다.#include <stdio.h>
#include "BinaryTree.h"
int main(void)
{
/*** 노드 생성 ***/
BTreeNode * bt1 = MakeBTreeNode();
BTreeNode * bt2 = MakeBTreeNode();
BTreeNode * bt3 = MakeBTreeNode();
BTreeNode * bt4 = MakeBTreeNode();
/*** 데이터 저장 ***/
SetData(bt1, 1);
SetData(bt2, 2);
SetData(bt3, 3);
SetData(bt4, 4);
/*** 연결 관계 생성 ***/
MakeLeftSubTree(bt1, bt2);
MakeRightSubTree(bt1, bt3);
MakeLeftSubTree(bt2, bt4);
printf("%d \n",
GetData(GetLeftSubTree(bt1))); // 2
printf("%d \n",
GetData(GetLeftSubTree(GetLeftSubTree(bt1)))); // 4
return 0;
}루트 노드를 언제 방문하는가에 따라 나뉜다.



재귀의 탈출 조건
NULL 인 경우 탈출한다.반복 패턴(중위 순회 기준)

void InorderTraverse(BTreeNode * bt)
{
if(bt == NULL) // bt가 NULL이면 탈출한다.
return;
InorderTraverse(bt->left);
printf("%d \n", bt->data); // 방문 시 다양한 함수 처리를 할 수 있다.
InorderTraverse(bt->right);
}
void DeleteTree(BTreeNode * bt)
{
if(bt == NULL)
return;
DeleteTree(bt->left);
DeleteTree(bt->right);
free(bt); // 방문시 처리 함수
}
참고: 윤성우의 열혈 자료구조