広告スペース

再帰関数

「自分自身を呼び出す関数」の仕組みを、コールスタックの可視化で理解しましょう。

再帰とは

再帰(recursion)とは、関数が自分自身を呼び出すプログラミング手法です。
ループで書ける処理も再帰で書けますが、問題の構造を分割して考えるときに特に威力を発揮します。
再帰には必ずベースケース(終了条件)が必要です。これがないと無限に呼び出しが続き、スタックオーバーフローになります。

階乗(factorial)

n! = n × (n-1) × ... × 1 を再帰で書くと、こうなります。
int factorial(int n) {
    if (n <= 1) return 1;   // ベースケース
    return n * factorial(n - 1); // 再帰呼び出し
}
動作の流れ(n=4の場合):
factorial(4) → 4 × factorial(3) → 4 × 3 × factorial(2) → 4 × 3 × 2 × factorial(1) → 4 × 3 × 2 × 1 = 24

コールスタック可視化

再帰呼び出しがどのようにスタックに積まれて戻っていくか見てみましょう。

フィボナッチ数列

フィボナッチ数列(0, 1, 1, 2, 3, 5, 8, 13, ...)は、2つの再帰呼び出しを行う例です。
int fib(int n) {
    if (n <= 0) return 0;
    if (n == 1) return 1;
    return fib(n - 1) + fib(n - 2);
}
注意: この素朴な実装は n が大きくなると指数的に遅くなります。fib(40) でも数秒かかることがあります。実用ではループやメモ化を使います。
n =

再帰の注意点

スタックオーバーフロー
ベースケースがないと無限再帰 → スタック領域を使い果たしてプログラムがクラッシュします。
パフォーマンス
同じ計算を何度もする再帰は非効率。メモ化(結果を保存)やループへの書き換えを検討しましょう。
再帰が適切な場面
木構造の探索、分割統治法(マージソート等)、数学的帰納法と対応する問題など。

確認クイズ

int mystery(int n) {
    if (n == 0) return 0;
    return n + mystery(n - 1);
}
printf("%d\n", mystery(5));

出力結果は?

5
15
120
0
解説: mystery(5) = 5 + mystery(4) = 5 + 4 + 3 + 2 + 1 + 0 = 15
これは 1〜n の合計を求める再帰関数です。factorial(n!)と混同しないよう注意。

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で演習問題も充実。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ