意志決定木
2分木の応用で最も単純な物として、意志決定木がある。
yes/no の答えを回答すると、最終的に「あなたの性格は✕✕です」と表示するようなヤツ。
struct Tree {
char* q_a ;
struct Tree* yes ;
struct Tree* no ;
} ;
top
\
あなたは勉強が好き?
/yes \no
ものづくりは好き? 人と話すのが好き?
/yes \no /yes \no
技術者タイプ ◯◯◯ 営業タイプ ◯◯◯
このような場合、プログラムは…
struct Tree* tcons( char*s, struct Tree*y, struct Tree*n )
{ struct Tree* ans ;
ans = (struct Tree*)malloc( sizeof( struct Tree ) ) ;
if ( ans != NULL ) {
ans->q_a = s ;
ans->yes = y ;
ans->no = n ;
}
return ans ;
}
void main() {
struct Tree* top =
tcons( "あなたは勉強が好き?" ,
tcons( "ものづくりは好き?" ,
tcons( "技術者タイプ , NULL , NULL ) ,
tcons( "...." , NULL , NULL ) ) ,
tcons( "人と話すのが好き?" ,
tcons( "営業タイプ" , NULL , NULL ) ,
tcons( "...." , NULL , NULL ) ) ) ;
struct Tree* p = top ;
while( p->yes != NULL && p->no != NULL ) {
char a[10] ;
printf( "%s" , p->q_a ) ;
scanf( "%s" , a ) ;
if ( strcmp( a , "yes" ) == 0 )
p = p->yes ;
else
p = p->no ;
}
printf( "%s¥n" , p->q_a ) ;
}
※ このプログラムの問題点は?
演算子と2分木
2分木の応用の例としては、式の表現などがある。
例えば、”1+2*3″という式があった場合、”(1+2)*3=9″なのか”1+(2*3)=7″なのか。(数学では演算子の優先順位から後者)、こういう演算子の優先順位をカッコで表さないためには、どうするか?
中置記法 1+2*3 = 1 + (2 * 3) +
/ \
前置記法 +,1,*,2,3 1 *
/ \
後置記法 1,2,3,*,+ 2 3
後置記法は、コンピュータで計算をする場合に都合が良く、ポーランド記法としてよく知られている。
コンピュータで式を表すデータを、2分木に表現することもできる。こういった文法や処理を表す木は、構文木とも呼ばれる。
演算子では、演算子の優先順位以外にも、左結合・右結合といったものも重要となる。
左結合演算子 1+2+3+4 → ((1+2)+3)+4 右結合演算子 x=y=z=0 → x = (y = (z=0))