#include "stdafx.h"
#include "BinaryTree.h"
BinaryTree::BinaryTree()
{
m_root = NULL;
}
BinaryTree::~BinaryTree()
{
m_Stack.Clear();
delete m_root;
}
//트리에 데이터 입력
void BinaryTree::Push(char data)
{
//루트가 NULL이라면 루트에 데이터 입력
if (m_root == NULL)
{
m_root = new NODE(data);
return;
}
//루트 노드부터 검색 시작
NODE* indexNode = m_root;
while (true)
{
//중복 데이터 입력 방지
if (indexNode->Data == data)
return;
//입력 받은 데이터가 현재 노드의 데이터 보다 작다면 -> 왼쪽 노드 체크
if (indexNode->Data > data)
{
//자식 노드가 비어있다면, 노드 생성 & 데이터 입력
if (indexNode->Left == NULL)
{
indexNode->Left = new NODE(data);
break;
}
else//아니라면 index노드에 현재 왼쪽 자식 노드 입력
indexNode = indexNode->Left;
}
else //입력 받은 데이터가 현재 노드의 데이터 보다 크다면 -> 오른쪽 노드 체크
{
//자식 노드가 비어있다면, 노드 생성 & 데이터 입력
if (indexNode->Right == NULL)
{
indexNode->Right = new NODE(data);
break;
}
else//아니라면 index노드에 현재 오른쪽 자식 노드 입력
indexNode = indexNode->Right;
}
}
}
//전위순회
void BinaryTree::TraversalPreorder(bool bUseStack)
{
printf("전위순회");
if (bUseStack)
printf("[스택]"), Preorder_Stack(m_root);
else
printf("[재귀]"), Preorder_Recursion(m_root);
printf("\n");
}
//중위 순회
void BinaryTree::TraversalInorder(bool bUseStack)
{
printf("중위순회");
if (bUseStack)
printf("[스택]"), Inorder_Stack(m_root);
else
printf("[재귀]"), Inorder_Recursion(m_root);
printf("\n");
}
//후위 순회
void BinaryTree::TraversalPostorder(bool bUseStack)
{
printf("후위순회");
if (bUseStack)
printf("[스택]"), Postorder_Stack(m_root);
else
printf("[재귀]"), Postorder_Recursion(m_root);
printf("\n");
}
//레벨 순회
void BinaryTree::TraversalLevelorder(void)
{
printf("레벨순회");
NODE* indexNode;
//큐 초기화
m_Queue.Init();
//루트노드 입력
m_Queue.Put(m_root);
//큐가 빌때까지 반복
while (!m_Queue.IsEmpty())
{
//제일 먼저 입력된 노드 수령
indexNode = m_Queue.Get();
//방문(출력)
PrintNode(indexNode->Data);
//왼쪽 노드가 있다면 왼쪽노드 큐에 입력
if (indexNode->Left != NULL)
m_Queue.Put(indexNode->Left);
//오른쪽 노드가 있다면 왼쪽노드 큐에 입력
if (indexNode->Right != NULL)
m_Queue.Put(indexNode->Right);
}
printf("\n");
}
//스택을 이용한 전위 순회
void BinaryTree::Preorder_Stack(NODE* rootNode)
{
NODE* indexNode;
m_Stack.Clear();
//스택에 제일먼저 루트를 입력
m_Stack.Push(rootNode);
//스택이 빌때까지 반복
while (!m_Stack.IsEmpty())
{
//스텍 최상단 노드 출력
indexNode = m_Stack.Pop();
//노드 데이터 프린트
PrintNode(indexNode->Data);
//오른쪽 노드가 있다면 스텍에 입력
StackNode(indexNode->Right);
//왼쪽 노드가 있다면 스텍에 입력 <= 후입선출(LIFO)이니까 먼저 출력됨
StackNode(indexNode->Left);
}
}
//재귀함수를 이용한 전위 순회
void BinaryTree::Preorder_Recursion(NODE* node)
{
if (node == NULL)
return;
//자신을 출력하고
PrintNode(node->Data);
//왼쪽 방문
Preorder_Recursion(node->Left);
//마지막으로 오른쪽 방문
Preorder_Recursion(node->Right);
}
//스택을 이용한 중위 순회
void BinaryTree::Inorder_Stack(NODE* rootNode)
{
NODE *indexNode = rootNode;
m_Stack.Clear();
while (true)
{
//현재 노드에서 도달 할 수 있는 최좌측 노드 찾기 & 경로에 있는 노드들 저장
while (indexNode != NULL)
{
//현재 노드 저장
m_Stack.Push(indexNode);
//다음 좌측 노드 지정
indexNode = indexNode->Left;
}
//스택에 노드가 있다면
if (!m_Stack.IsEmpty())
{
//가장 늦게 이력된 노드 수령
indexNode = m_Stack.Pop();
//그 노드 데이터 출력
PrintNode(indexNode->Data);
//현재 노드의 우측노드를 다음 노드로 => 다음 반복에서 상위 While문에 있는 m_Stack.Push로 스택에 입력됨
indexNode = indexNode->Right;
}
else
break;
}
}
//재귀함수를 이용한 중위 순회
void BinaryTree::Inorder_Recursion(NODE * node)
{
if (node == NULL)
return;
//왼쪽 노드 재귀함수 실행
Inorder_Recursion(node->Left);
//자신 데이터 출력
PrintNode(node->Data);
//오른쪽 노드 재귀함수 실행
Inorder_Recursion(node->Right);
}
//스택을 이용한 후위 순회
void BinaryTree::Postorder_Stack(NODE* node)
{
m_Stack.Clear();
while (true)
{
while (NULL != node)
{
//현재 노드를 2번 입력
m_Stack.Push(node);
m_Stack.Push(node);
//왼쪽 노드로 이동
node = node->Left;
}
if (!m_Stack.IsEmpty())
{
node = m_Stack.Pop();
//현재 노드의 첫번째 방문일때, 오른쪽으로 이동
if (!m_Stack.IsEmpty() && node == m_Stack.Peek())
{
node = node->Right;
}
//현재 노드를 두번째 방문 했을때 출력한다.
else
{
PrintNode(node->Data);
node = NULL;
}
}
else
{
break;
}
}
}
//재귀함수를 이용한 후위 순회
void BinaryTree::Postorder_Recursion(NODE *node)
{
if (node == NULL)
return;
//왼쪽 노드 재귀함수 실행
Postorder_Recursion(node->Left);
//오른쪽 노드 재귀함수 실행
Postorder_Recursion(node->Right);
//자신 데이터 출력
PrintNode(node->Data);
}
//노드 데이터 프린트
void BinaryTree::PrintNode(char data)
{
printf(" -> %c", data);
}
//스택에 노드 입력
void BinaryTree::StackNode(NODE *node)
{
if (node != NULL)
m_Stack.Push(node);
}