수식 트리를 구축하는 방법
1. 중위 표기식을 후위 표기식으로 변환한다.
중위 표기식을 후위 표기식으로 변환하는것은 생략한다. https://owwowo.tistory.com/127?category=1084279
2. 후위 표기식 기반 수식 트리 구축 알고리즘을 이용하여 구축한다.
①수식을 뒤에서부터 앞쪽으로 읽어나간다.
②수식에서 제일 마지막에 있는 토큰은 루트 노드가 된다. 후위 표기식에서 가장 마지막에 있는 토큰은 항상 연산자이다.
③수식에서 읽어낸 토큰이 연산자인 경우에는 가지 노드가 되며, 이 토큰 다음에 따라오는 두개의 토큰은 각각 오른쪽 자식 노드와 왼쪽 자식 노드가 된다. 단, 다음 토큰에도 연속해서 연산자인 경우에는 이 토큰으로부터 만들어지는 하위 트리가 완성된 이후에 읽어낸 토큰이 왼쪽 자식 노드가 된다.
④수식에서 읽어낸 토큰이 숫자이면 이 노드는 잎 노드이다.
// gcc -o Test_ExpressionTree.exe Test_ExpressionTree.c ExpressionTree.c; ./Test_ExpressionTree.exe
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char ElementType;
typedef struct tagETNode
{
struct tagETNode* Left;
struct tagETNode* Right;
ElementType Data;
} ETNode;
ETNode* ET_CreateNode( ElementType NewData )
{
ETNode* NewNode = (ETNode*)malloc( sizeof(ETNode) );
NewNode->Left = NULL;
NewNode->Right = NULL;
NewNode->Data = NewData;
return NewNode;
}
void ET_DestroyNode( ETNode* Node )
{
free(Node);
}
void ET_DestroyTree( ETNode* Root )
{
if ( Root == NULL )
return;
ET_DestroyTree( Root->Left );
ET_DestroyTree( Root->Right );
ET_DestroyNode( Root );
}
void ET_PreorderPrintTree( ETNode* Node )
{
if ( Node == NULL )
return;
printf( " %c", Node->Data );
ET_PreorderPrintTree( Node->Left );
ET_PreorderPrintTree( Node->Right );
}
void ET_InorderPrintTree( ETNode* Node )
{
if ( Node == NULL )
return;
printf( "(" );
ET_InorderPrintTree( Node->Left );
printf( "%c", Node->Data );
ET_InorderPrintTree( Node->Right );
printf( ")" );
}
void ET_PostorderPrintTree( ETNode* Node )
{
if ( Node == NULL )
return;
ET_PostorderPrintTree( Node->Left );
ET_PostorderPrintTree( Node->Right );
printf( " %c", Node->Data );
}
void ET_BuildExpressionTree( char* PostfixExpression, ETNode** Node )
{
ETNode* NewNode = NULL;
int len = strlen( PostfixExpression );
char Token = PostfixExpression[ len -1 ];
PostfixExpression[ len-1 ] = '\0';
switch ( Token )
{
/* 연산자인 경우 */
case '+': case '-': case '*': case '/':
(*Node) = ET_CreateNode( Token );
ET_BuildExpressionTree( PostfixExpression, &(*Node)->Right );
ET_BuildExpressionTree( PostfixExpression, &(*Node)->Left );
break;
/* 피연산자인 경우 */
default :
(*Node) = ET_CreateNode( Token);
break;
}
}
double ET_Evaluate( ETNode* Tree )
{
char Temp[2];
double Left = 0;
double Right = 0;
double Result = 0;
if ( Tree == NULL )
return 0;
switch ( Tree->Data )
{
/* 연산자인 경우 */
case '+': case '-': case '*': case '/':
Left = ET_Evaluate( Tree->Left );
Right = ET_Evaluate( Tree->Right );
if ( Tree->Data == '+' ) Result = Left + Right;
else if ( Tree->Data == '-' ) Result = Left - Right;
else if ( Tree->Data == '*' ) Result = Left * Right;
else if ( Tree->Data == '/' ) Result = Left / Right;
break;
/* 피연산자인 경우 */
default :
memset(Temp, 0, sizeof(Temp));
Temp[0] = Tree->Data;
Result = atof(Temp);
break;
}
return Result;
}
int main( void )
{
ETNode* Root = NULL;
char PostfixExpression[20] = "71*52-/";
ET_BuildExpressionTree( PostfixExpression, &Root);
/* 트리 출력 */
printf("Preorder ...\n");
ET_PreorderPrintTree( Root );
printf("\n\n");
printf("Inorder ... \n");
ET_InorderPrintTree( Root );
printf("\n\n");
printf("Postorder ... \n");
ET_PostorderPrintTree( Root );
printf("\n");
printf("Evaulation Result : %f \n", ET_Evaluate( Root ) );
/* 트리 소멸시키기 */
ET_DestroyTree( Root );
return 0;
}
'자료구조' 카테고리의 다른 글
그래프 (Graph) (0) | 2024.02.03 |
---|---|
Tree(3) - Disjoint Set(분리 집합) (0) | 2022.07.10 |
Tree(2) - Binary Tree (0) | 2022.07.10 |
Tree(1) - Tree 구현 (0) | 2022.07.10 |
Queue(2) - Linked Queue (0) | 2022.07.08 |