Ch08. ツリー(Tree)
08-1. ツリーの概要
ひせんけいデータこうぞう
ツリーアクセス
ツリーは階層関係を表す資料構造です
木が表現できる
枝を引く
[決定ツリー]
ツリー用語の概要
ツリー内のコンポーネントのA、B、C、D、Eなどの要素
ノードとノードを接続するベースライン
ツリー上部のAと同じノード
ノード
A、B等のノード(端末ノードを除く)
内部ノードは端末ノードではなく、非端末ノードとも呼ばれる
特定のノードの上にあるすべてのノード
特定のノードの下にあるすべてのノード
バイナリツリーとサブツリー
大木に属する大木
-ルートノードを中心に2つのサブツリーに分割
-分割された2つのサブツリーもバイナリツリー
空セットノードはバイナリツリーの判定でノードとして認定される
完全バイナリツリーと完全バイナリツリー
上から下、左から右の順に塗りつぶします.
08-2. バイナリツリーの実装
バイナリツリーの実装方法:配列または接続リスト
ツリーを表現するには、接続リストが柔軟になります.
ただし,ツリーが完了した後に非常に頻繁にナビゲーションを行うツリーであれば,配列を用いて実現する.探索は簡単で速いので
タイトルファイルで定義されている構造体について
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
typedef int BData;
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
ヘッダファイルで宣言された関数の機能
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
typedef int BData;
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);
:ノードの作成BTData GetData(BTreeNode * bt);
:ノードに格納されているデータを返すvoid SetData(BTreeNode * bt, BTData data);
:ノードBTreeNode * GetLeftSubTree(BTreeNode * bt);
:左サブツリーアドレス値BTreeNode * GetRightSubTree(BTreeNode * bt);
:右側サブツリーアドレス値バイナリツリー構造のADT
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);
バイナリツリーの実装
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
BTreeNode * MakeBTreeNode(void)
{
BTreeNode *nd = (BTreeNode*)malloc(sizeof(BTreeNode));
nd->left = NULL;
nd->right = NULL;
return nd;
}
BTData GetData(BTreeNode * bt)
{
return bt->data;
}
void SetData(BTreeNode * bt, BTData data)
{
bt->data = data;
}
BTreeNode * GetLeftSubTree(BTreeNode * bt)
{
return bt->left;
}
BTreeNode * GetRightSubTree(BTreeNode * bt)
{
return bt->right;
}
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub)
{
if(main->left != NULL)
free(main->left);
main->left = sub;
}
void MakeRightSubTree(BTreeNode * main, BTreeNode * sub)
{
if(main->right != NULL)
free(main->right);
main->right = sub;
}
08-3. バイナリツリーを巡回
巡回の3つの方法
巡回の再帰表現
void InorderTraverse(BTreeNode * bt) // 이진 트리 전체를 중위 순회하는 함수
{
InorderTraverse(bt->left); // 1단계 왼쪽 서브 트리의 순회
printf(“%d \n”, bt->data); // 2단계 루트 노드의 방문
InorderTraverse(bt->right); // 3단계 오른쪽 서브 트리의 순회
}
家に帰る条件は定義されていませんノードへのアクセスはデータの出力のみです
家に帰る条件
void InorderTraverse(BTreeNode * bt) // 이진 트리 전체를 중위 순회하는 함수
{
if(bt == NULL) // bt가 NULL이면 재귀 탈출!
return;
InorderTraverse(bt->left); // 1단계 왼쪽 서브 트리의 순회
printf(“%d \n”, bt->data); // 2단계 루트 노드의 방문
InorderTraverse(bt->right); // 3단계 오른쪽 서브 트리의 순회
}
フォワードツアーvoid PreorderTraverse(BTreeNode * bt)
{
if(bt == NULL)
return;
printf(“%d \n”, bt->data); // 전위 순회이므로 루트 노드 먼저 방문
PreorderTraverse(bt->left);
PreorderTraverse(bt->right);
}
後巡void PostorderTraverse(BTreeNode * bt)
{
if(bt == NULL)
return;
PostorderTraverse(bt->left);
PostorderTraverse(bt->right);
printf(“%d \n”, bt->data); // 후위 순회이므로 루트 노드 나중에 방문!
}
08-4. 「式ツリー」(Expression Tree)の実装
ルートノードに格納された演算子を演算し、2つのサブノードに格納された2つの被演算子を演算する
中位マークの修飾->後位マークの修飾->修飾ツリー
式ツリーの実装に必要なツールとヘッダファイルの定義
#ifndef __EXPRESSION_TREE_H__
#define __EXPRESSION_TREE_H__
#include "BinaryTree2.h"
BTreeNode * MakeExpTree(char exp[]); // 수식 트리 구성
int EvaluateExpTree(BTreeNode * bt); // 수식 트리 계산
void ShowPrefixTypeExp(BTreeNode * bt); //전위 표기법 기반 출력
void ShowInfixTypeExp(BTreeNode * bt); // 중위 표기법 기반 출력
void ShowPostfixTypeExp(BTreeNode * bt); //후위 표기법 기반 출력
#endif
接尾辞
#ifndef __EXPRESSION_TREE_H__
#define __EXPRESSION_TREE_H__
#include "BinaryTree2.h"
BTreeNode * MakeExpTree(char exp[]); // 수식 트리 구성
int EvaluateExpTree(BTreeNode * bt); // 수식 트리 계산
void ShowPrefixTypeExp(BTreeNode * bt); //전위 표기법 기반 출력
void ShowInfixTypeExp(BTreeNode * bt); // 중위 표기법 기반 출력
void ShowPostfixTypeExp(BTreeNode * bt); //후위 표기법 기반 출력
#endif
式ツリーの構成方法
BTreeNode * MakeExpTree(char exp[])
{
Stack stack;
BTreeNode * pnode;
int expLen = strlen(exp);
int i;
StackInit(&stack);
for(i = 0; i < expLen; i++)
{
pnode = MakeBTreeNode();
if(isdigit(exp[i])) // 피연산자라면 ...
{
SetData(pnode, exp[i]-'0'); //문자를 정수로 바꿔서 저장
}
else // 연산자라면...
{
MakeRightSubTree(pnode, SPop(&stack));
MakeLeftSubTree(pnode, SPop(&stack));
SetData(pnode, exp[i]);
}
SPush(&stack, pnode);
}
return SPop(&stack);
}
式ツリーを巡回
void ShowPrefixTypeExp(BTreeNode * bt) // 전위 표기법의 수식으로
{
PreorderTraverse(bt, ShowNodeData);
}
void ShowInfixTypeExp(BTreeNode * bt) // 중위 표기법의 수식으로
{
InorderTraverse(bt, ShowNodeData);
}
void ShowPostfixTypeExp(BTreeNode * bt) // 후위 표기법의 수식으로
{
PostorderTraverse(bt, ShowNodeData);
}
数式ツリーの計算
int EvaluateExpTree(BTreeNode * bt)
{
int op1, op2;
if(GetLeftSubTree(bt) == NULL && GetRightSubTree(bt) == NULL) // 단말 노드라면
return GetData(bt);
op1 = GetData(GetLeftSubTree(bt)); // 첫 번째 피연산자
op2 = GetData(GetRightSubTree(bt)); // 두 번째 피연산자
switch(GetData(bt)) // 연산자를 확인하여 연산을 진행
{
case ‘+’ :
return op1+op2;
case ‘-‘ :
return op1-op2;
case ‘*’ :
return op1*op2;
case ‘/‘ :
return op1/op2;
}
return 0;
}
Reference
この問題について(Ch08. ツリー(Tree)), 我々は、より多くの情報をここで見つけました https://velog.io/@www_castlehi/Ch08.-트리Treeテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol