C言語:再帰(初級)

序文

実はこの記事を書く前に再帰についての記事を書いたのですが、その記事は二分木のことを考えると初心者には難しいです。したがって、再帰の開始に関するこの記事があります。(興味のある友人は、バイナリ ツリーの深さ優先探索関連トピックを参照してください。

再帰の概要

C 言語では、関数はそれ自体を呼び出すことができ、この呼び出しプロセスは再帰と呼ばれます。そして、再帰はその名前が示すように、関数呼び出しを渡し、関数の結果を返す再帰には大きなものを小さなものに還元する機能があり、コードを書くのは簡単ですが、理解するのが非常に抽象的です。
ここに画像の説明を挿入
画像からわかるように、再帰が必要です再帰を終了する条件そうでない場合は、無限に再帰します。
一般に、ループを使用できる場合は、通常、再帰を使用できます。

3 つの軸の再帰的使用

1. 再帰が使用できるかどうかを判断する

再帰は通常、機能を規則的に繰り返したり実行したりできる場合に使用されます。

2. 終了条件の決定

再帰関数を使用する場合は、いつ停止するかを考え、終了に必要な条件を調べます。

3. 漸化式を求める

再帰を使う場合は、何を渡して何を返すかを考えて関係式を書く必要があります。もちろん、関数の結果がどうなるかを知る必要があります。一般に、次のように始めることができます。始めるための簡単な例

以下では 2 つの例を使用して、これら 3 つの軸の使用法を説明します。

1. フィボナッチ数列

これは再帰を使用する非常に古典的な例です。1、1、2、3、5、8、13、21
... という順序があります。3 番目の数値から始まり、各数値は前の 2 つの数値の合計になります。 。n番目の数字は何ですか?

3軸使用

   由题目知道,第三个数开始,每个数是前两个数之和,这种规律性符合我们
   使用递归;例如我们求第三个数,我们很容易知道是1+1=2,但我们此时
   要想好怎么把这个关系式转换成递归的关系式。第一个1为第一个数,第二个
   为第二个数,那么就将他转换为函数形式即可。这时我们很容易知道,n进入
   函数后是不断递减的,那么终止条件(传递函数的终点)就是第一个数和第二个
   数。

ここに画像の説明を挿入

コード

#include<stdio.h>
 int fib(int n)
 {
    
    
 //递归终止条件
     if(n==1||n==2)
    {
    
    
         return 1;
     }
     //递归关系式
     return fib(n-1)+fib(n-2);
 }
 int main()
 {
    
    
 int n=5;
 int sum=fib(n);
 printf("%d",sum);
 return 0;
 }
  结果为:5

2. nのk乗を計算します。

3軸使用

n を何度も乗算すると、再帰が使用できることがわかります。例えば、2の3乗を求めます
ここに画像の説明を挿入
と、図から1のときが終了条件であることが分かり、関係式はn*以降の数字になります。
ここに画像の説明を挿入

#include<stdio.h>
int power(int n,int k)
{
    
    
    if(k==1)
    {
    
    
        return n;
    }
        return n*power(n,k-1);
}
int main()
{
    
    
	power(2,5);
	return 0;
}
   结果:32

ループと再帰

上で述べたように、ループが可能であれば、再帰は通常実行できます。ループを使用して問題を解決する方が良い場合もありますが、再帰を使用した方が良い場合もあります。再帰スキームはより簡潔ですが、ループほど効率的ではありません。
たとえば、n の階乗を求めます。
コードは以下のように表示されます:

#include<stdio.h>
//递归形式
int Fab(int n)
{
    
    
    if(n==1)
    {
    
    
        return 1;
    }
    return Fab(n-1)*n;
}
//循环迭代形式
int Fab(int n)
{
    
    
    int sum=1;
   for(int i=1;i<n;i++)
    {
    
    
        sum=sum*(i+1);
        
    }
    return sum;
}
int main()
{
    
    
    int n=5;
    int sum=Fab(n);
    printf("%d",sum);
    return 0;
}
结果:120

コードを見ると、再帰形式は明らかにはるかに単純ですが、実際には、それを使用するプロセスが非常に複雑であることがわかります。なぜそんなことを言うのですか?関数を呼び出すと、一時的にメモリ内にストレージ用のスペースを開く必要があり、このスペース (スタック領域) は関数が終了すると返されることがわかっています。再帰関数が使用されている場合、常に関数は使い果たされる前に次の関数に入ります、関数はスペースを空ける必要があり、サイクルが行ったり来たりしてメモリがさらに占有されます。ループはちょうど関数内で使用する, そのため、スペースが 1 つだけ開かれます。
ここに画像の説明を挿入
したがって、関数で再帰とループを使用できる場合は、ループが優先されます

再帰関数配置の順序問題

再帰を使用するプロセスでは、最初に何を実行し、次に何を実行するかを知る必要があります。再帰関数を実行するステートメントの前に置くか後ろに置くかは非常に重要です。
たとえば、整数を数値として出力し、数値をスペースで区切って出力したいとします。
例: 1729 を 1 7 2 9
コードとして出力します。

#include<stdio.h>
void printf_lone(int n)
{
    
    
    if(n<10)
    {
    
    
        printf("%d ",n);
        return;
    }
    printf("%d ",n%10);
    printf_lone(n/10);
   
}
int main()
{
    
    
    int n=1729;
    printf_lone(n);
    return 0;
}
结果:9 2 7 1

望んでいたものとは逆の結果になってしまったので、この時点で私たちの再帰的思考が間違っているかどうかを考えなければなりません。考えてみると、私たちは数字の右側から左側に向かっていることがわかりました。最初に出力するときは、最初に 9 を出力し、順番に再帰する必要があります。そうすると結果は逆になります。したがって、正しいコードは次のとおりです。

#include<stdio.h>
void printf_lone(int n)
{
    
    
    if(n<10)
    {
    
    
        printf("%d ",n);
        return;
    }
    printf_lone(n/10);
    printf("%d ",n%10);
   
}
int main()
{
    
    
    int n=1729;
    printf_lone(n);
    return 0;
}
结果 :1 7 2 9

だからはっきり言っておきます再帰はどこから来るのか、正しいコードを書くために、最初に何を実行し、何を後で実行するか。

要約する

ここでは、上記の例から明らかなように、再帰の使用法といくつかの注意事項について簡単に説明します。通常、終了条件が最初に配置されます、次に再帰関係。再帰的思考を強化したい場合は、特定の演習を通じて行うことができます。C 言語を学習する上で、この再帰的な考え方は依然として非常に重要であり、ループによって解決することはできません。
それでは、今日はここまでです、ご覧いただきありがとうございました。

おすすめ

転載: blog.csdn.net/m0_74068921/article/details/130415635
おすすめ