
오늘의 문제는 이진트리 문제이다. C언어를 조금씩 하면서 파이썬으로 알고리즘을 할 때 이해가 잘 가지 않았던 부분이 몬가 이해가 좀 더 잘되는 느낌이다.
문제는 트리에 있는 최솟값을 출력하는 함수를 작성하는 것이다. 아래와 같이 문제가 있다.
주어진 이진 트리에서 가장 작은 값을 반환하는 C 함수를 작성하시오.
int smallestValue(BTNode *node);

int smallestValue(BTNode *node)
{
// <limits.h> 헤더 추가해서 INT_MAX 사용
// INT_MAX -> INT의 수 중 가장 큰 수
// 리턴을 0이 아니라 큰 수로 하는 이유 리턴 시 0을 리턴하게되면 0이 가장 작은 값이 되버려서 최솟값은 항상 0이 나오기 때문
// 기저 조건
if (node == NULL) return INT_MAX;
// 왼쪽 서브 트리 재귀
int leftMin = smallestValue(node->left);
// 오른쪽 서브 트리 재귀
int rightMin = smallestValue(node->right);
// 현재 작은 값은 현재 노드의 값
int currentMin = node->item;
// 왼쪽에 있는 값이 현재 값보다 작을 때
if (leftMin < currentMin) {
currentMin = leftMin;
}
// 오른쪽에 있는 값이 현재 값보다 작을 때
if (rightMin < currentMin) {
currentMin = rightMin;
}
// 현재 작은 값 리턴
return currentMin;
}
//////////////////////////////////////////////////////////////////////////////////
/* CE1007/CZ1007 Data Structures
Lab Test: Section E - Binary Trees Questions
Purpose: Implementing the required functions for Question 7 */
//////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//////////////////////////////////////////////////////////////////////////////////
typedef struct _btnode
{
int item;
struct _btnode *left;
struct _btnode *right;
} BTNode; // You should not change the definition of BTNode
/////////////////////////////////////////////////////////////////////////////////
typedef struct _stackNode
{
BTNode *btnode;
struct _stackNode *next;
} StackNode;
typedef struct _stack
{
StackNode *top;
} Stack;
///////////////////////// Function prototypes ////////////////////////////////////
// You should not change the prototypes of these functions
int smallestValue(BTNode *node);
BTNode *createBTNode(int item);
BTNode *createTree();
void push( Stack *stack, BTNode *node);
BTNode* pop(Stack *stack);
void printTree(BTNode *node);
void removeAll(BTNode **node);
///////////////////////////// main() /////////////////////////////////////////////
int main()
{
char e;
int c, value;
BTNode *root;
c = 1;
root = NULL;
printf("1: Create a binary tree.\n");
printf("2: Smallest value;\n");
printf("0: Quit;\n");
while(c != 0)
{
printf("Please input your choice(1/2/0): ");
if( scanf("%d",&c) > 0)
{
switch(c)
{
case 1:
removeAll(&root);
root = createTree();
printf("The resulting binary tree is: ");
printTree(root);
printf("\n");
break;
case 2:
value = smallestValue(root);
printf("Smallest value of the binary tree is: %d\n",value);
removeAll(&root);
break;
case 0:
removeAll(&root);
break;
default:
printf("Choice unknown;\n");
break;
}
}
else
{
scanf("%c",&e);
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////
int smallestValue(BTNode *node)
{
// <limits.h> 헤더 추가해서 INT_MAX 사용
// INT_MAX -> INT의 수 중 가장 큰 수
// 리턴을 0이 아니라 큰 수로 하는 이유 리턴 시 0을 리턴하게되면 0이 가장 작은 값이 되버려서 최솟값은 항상 0이 나오기 때문
// 기저 조건
if (node == NULL) return INT_MAX;
// 왼쪽 서브 트리 재귀
int leftMin = smallestValue(node->left);
// 오른쪽 서브 트리 재귀
int rightMin = smallestValue(node->right);
// 현재 작은 값은 현재 노드의 값
int currentMin = node->item;
// 왼쪽에 있는 값이 현재 값보다 작을 때
if (leftMin < currentMin) {
currentMin = leftMin;
}
// 오른쪽에 있는 값이 현재 값보다 작을 때
if (rightMin < currentMin) {
currentMin = rightMin;
}
// 현재 작은 값 리턴
return currentMin;
}
//////////////////////////////////////////////////////////////////////////////////
BTNode *createBTNode(int item)
{
BTNode *newNode = malloc(sizeof(BTNode));
newNode->item = item;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
//////////////////////////////////////////////////////////////////////////////////
BTNode *createTree()
{
Stack stack;
BTNode *root, *temp;
char s;
int item;
stack.top = NULL;
root = NULL;
printf("Input an integer that you want to add to the binary tree. Any Alpha value will be treated as NULL.\n");
printf("Enter an integer value for the root: ");
if(scanf("%d",&item) > 0)
{
root = createBTNode(item);
push(&stack,root);
}
else
{
scanf("%c",&s);
}
while((temp =pop(&stack)) != NULL)
{
printf("Enter an integer value for the Left child of %d: ", temp->item);
if(scanf("%d",&item)> 0)
{
temp->left = createBTNode(item);
}
else
{
scanf("%c",&s);
}
printf("Enter an integer value for the Right child of %d: ", temp->item);
if(scanf("%d",&item)>0)
{
temp->right = createBTNode(item);
}
else
{
scanf("%c",&s);
}
if(temp->right != NULL)
push(&stack,temp->right);
if(temp->left != NULL)
push(&stack,temp->left);
}
return root;
}
void push( Stack *stack, BTNode *node)
{
StackNode *temp;
temp = malloc(sizeof(StackNode));
if(temp == NULL)
return;
temp->btnode = node;
if(stack->top == NULL)
{
stack->top = temp;
temp->next = NULL;
}
else
{
temp->next = stack->top;
stack->top = temp;
}
}
BTNode* pop(Stack *stack)
{
StackNode *temp, *top;
BTNode *ptr;
ptr = NULL;
top = stack->top;
if(top != NULL)
{
temp = top->next;
ptr = top->btnode;
stack->top = temp;
free(top);
top = NULL;
}
return ptr;
}
void printTree(BTNode *node)
{
if(node == NULL) return;
printTree(node->left);
printf("%d ",node->item);
printTree(node->right);
}
void removeAll(BTNode **node)
{
if(*node != NULL)
{
removeAll(&((*node)->left));
removeAll(&((*node)->right));
free(*node);
*node = NULL;
}
}