// recursion.c -- 2分木を扱う再帰関数の例 #include <stdio.h> #include <stdlib.h> #include <ctype.h> // 2分木のデータ構造 typedef struct _tree { char node; // 節のデータ (1文字) struct _tree *left; // 左の子へのポインタ struct _tree *right; // 右の子へのポインタ } Tree; // 2分木の節の生成 Tree *node(char c, Tree *l, Tree *r) { Tree *t = (Tree *) malloc(sizeof(Tree)); if (t == NULL) { perror("malloc() failed in node()"); exit(EXIT_FAILURE); } t->node = c; t->left = l; t->right = r; return t; } // 2分木の葉の生成 Tree *leaf(char c) { return node(c, NULL, NULL); } // 木を再帰的に表示 void show(const Tree *t) { if (t == NULL) { putchar('#'); } else { putchar(t->node); putchar('('); show(t->left); putchar(','); show(t->right); putchar(')'); } } // 木の大きさ(節の総数)を再帰的に計算 int size(const Tree *t) { if (t == NULL) return 0; else return (size(t->left) + size(t->right) + 1); } // 木の大きさの再帰計算の様子を表示 int display(const Tree *t) { static int depth = -1; int i, size; depth++; // 関数の開始直後,節情報を表示 for (i = 1; i <= depth; i++) printf("> "); if (t == NULL) printf("#\n"); else printf("'%c'\n", t->node); // 節数の計算本体 if (t == NULL) size = 0; else size = display(t->left) + display(t->right) + 1; // 関数の終了直前,部分木の大きさを表示 for (i = 1; i <= depth; i++) printf("> "); printf("size = %d\n", size); depth--; return size; } // 木を表す文字列,木の節数,節数の再帰計算の過程 を順に表示 int main(void) { Tree *t = node('+', // 算術式 a*b + c/d を表す木 node('*', leaf('a'), leaf('b')), node('/', leaf('c'), leaf('d')) ); printf("t = "); show(t); putchar('\n'); printf("size(t) = %d\n", size(t)); printf("computation of size(t) :\n"); display(t); // 処理を続けるなら t が指す木の記憶域を開放する return EXIT_SUCCESS; }