Python基礎シリーズ - 再帰関数の認識

目次

1. 再帰関数

1.コンセプト

2. 特長

3. 個人的な概要 

2. 任意の数 n の階乗を求める練習をする

1. 一般的な方法

2. 再帰的方法

 3. 末尾再帰法

3. フィボナッチ数列の練習

1. 再帰的書き込み


1. 再帰関数

1.コンセプト

        再帰関数: 独自の関数を呼び出すことは再帰関数であり
        、行ったり来たり、戻ったりします。

2. 特長

関数の実行時には、スタック フレーム スペースと呼ばれるスペースを確保するためにメモリが必要です。

再帰:
(1) 行きのプロセスは、スタック フレーム スペースを継続的にオープンします。戻りの場合、スタック フレーム スペースを継続的に解放します。再帰関数は、スタック フレーム スペースを継続的にオープンおよび解放する完全なプロセスです (
2
) ) 戻るときのトリガー メカニズムは 2 つあります。関数空間の最後の層が完全に実行されるか、底に到達してリバウンドします (カービンに戻ります)。(3) 再帰関数を作成するときは、ジャンプを与える必要があります。
out 条件、再帰の層が多すぎる場合、使用はお勧めできません。メモリ オーバーフローやブルー スクリーンが発生しやすくなります。 (4) 再帰
呼び出しスペースの各層は独立した個別のものであり、独立したコピーであり、リソースは共有されません。 、価値の移転は返品を通じて完了できます

     公式には、特にマシンによると、再帰の最大深さは 1000 層です。

def deepfunc():
    deepfunc()
    
报错:
[Previous line repeated 996 more times]

3. 個人的な概要 

再帰とは、関数が自分自身を呼び出す処理のことで、再帰が見つかったら戻る処理を考える必要がありますが、再帰の処理は最終値を見つけるか返すだけで、結果は出力されません。私たちの操作は主に再帰のプロセスによって返された値であり、それは深い谷でエコーを止めるようなものです。

2. 任意の数 n の階乗を求める練習をする

1. 一般的な方法

def func(n):
	total = 1
	for i in range(1,n+1):
		total *= i
		"""
		total = total * i => 1 * 1
		total = total * i => 1 * 1 * 2
		total = total * i => 1 * 1 * 2 * 3
		total = total * i => 1 * 1 * 2 * 3 * 4 
		total = total * i => 1 * 1 * 2 * 3 * 4 * 5
		"""
	return total
res = func(5) 
print(res)

2. 再帰的方法

def func(n):
	if n <= 1:
		return 1
	return n * func(n - 1)

res = func(5)
print(res)
# 代码解析:
# 去的过程
n = 5  return 5 * func(5 - 1) => 5*func(4)
n = 4  return 4 * func(4 - 1) => 4*func(3)
n = 3  return 3 * func(3 - 1) => 3*func(2)
n = 2  return 2 * func(2 - 1) => 2*func(1)
n = 1  return 1

# 回的过程
n = 2  return 2*func(1) => 2*1       [func(2)]
n = 3  return 3*func(2) => 3*2*1     [func(3)]
n = 4  return 4*func(3) => 4*3*2*1   [func(4)]
n = 5  return 5*func(4) => 5*4*3*2*1 [func(5)]
res = func(5) <=> 5*4*3*2*1 = 120
"""

# 通俗点
看着这个式子,n=5时,不满足<=1,跳到func(n-1)中,开始计算func(4),依旧不满足,直到n=1,才可以直接return 1;
到达终点后开始反弹,回到2,得出return 2 * 1,回到3,得出3 * func(2)也就是3*2*1,以此类推

 3. 末尾再帰法

再帰とは層ごとに空間を開くことです。末尾再帰は特殊な再帰です。元の空間に直接開くのが特徴です。関数を何回呼び出しても、必要な空間は 1 つだけです。利点: space の最後の層の結果のみを考慮する必要があります
。リターン プロセスを考慮する必要はありません。
注: 末尾再帰ではパラメータ演算に値を入れる必要があります。

def jiecheng(n,endval=1):
	if n <= 1:
		return endval	
	return jiecheng(n-1, endval*n)
print(jiecheng(5))
# 代码解析:
# 去的过程
n = 5,endval = 1  
	return jiecheng(5-1,endval*n ) => return jiecheng(4,1*5)
n = 4,endval = 1*5
	return jiecheng(4-1,endval*n ) => return jiecheng(3,1*5*4)
n = 3,endval = 1*5*4
	return jiecheng(3-1,endval*n ) => return jiecheng(2,1*5*4*3)
n = 2,endval = 1*5*4*3
	return jiecheng(2-1,endval*n ) => return jiecheng(1,1*5*4*3*2)
n = 1,endval = 1*5*4*3*2
	if 1 <= 1  条件满足 return endval => return 1*5*4*3*2
	
# 回的过程
n = 2  return 1*5*4*3*2
n = 3  return 1*5*4*3*2
n = 4  return 1*5*4*3*2
n = 5  return 1*5*4*3*2
到此程序全部结束;
"""

为什么尾递归不需要考虑回的过程呢,因为函数目的是return endval,而endval的值已经在计算过程中出来了,即使返回上一层,程序会默认目的已达成,继续返回。
为什么要参数默认写死endval=1呢,因为阶乘就是1*2*。。。这种格式,我们需要给一个初始值,意味着这个1不是固定的,是根据实际情况来,写死也是为了用户只关注n的值即可

3. フィボナッチ数列の練習

1. 再帰的書き込み

def feb(n):
	if n ==1 or n == 2:
		return 1
	# 当前值n = 上一个值(n-1) + 上上个值(n-2)
	return feb(n-1) + feb(n-2)

res = feb(5)
print(res)

#代码解析:
斐波那契数列的定义是:第一个数为1,第二个数为1,从第三个数开始,每个数均为前两个数之和。

n = 5 
return feb(4) + feb(3)
       feb(3) + feb(2) + feb(3)
       feb(2) + feb(1) + feb(2) + feb(3)
       feb(2) + feb(1) + feb(2) + feb(2) + feb(1)
       1+1+1+1+1=5

首先,我们将函数调用 feb(5) 传入参数5。
在函数内部,我们首先判断n的值是否等于1或2。由于5不等于1或2,所以我们将跳过这个条件语句。

接下来,我们将执行这行代码 return feb(n-1) + feb(n-2),由于n等于5,因
此时我们需要求出斐波那契数列的第5个数。根据斐波那契数列的定义,第5个数应该是前两个数之和,即第4个数和第3个数之和。

然后,我们需要计算 feb(4) 和 feb(3) 的值。首先,我们将调用 feb(4)。
在 feb(4) 函数内部,我们也需要计算斐波那契数列的第4个数,即第3个数和第2个数之和。因此,我们需要调用 feb(3) 和 feb(2) 来计算这个值。

在 feb(3) 函数内部,我们需要计算斐波那
那契数列的第3个数,即第2个数和第1个数之和。因此,我们需要调用 feb(2) 和 feb(1) 来计算这个值。



在 feb(2) 函数内部,由于 n 的值等于2,因此我们将直接返回1。

在 feb(1) 函数内部,由于 n 的值等于1,因此我们也将直接返回1。

现在,我们已经得到了 feb(2) 和 feb(1) 的值,因此我们可以计算 feb(3) 的值。根据斐波那契数列的定义,第3个数应该是前两个数之和,即1+1=2。因此,feb(3) 的返回值为2。

接下来,我们已经得到了 feb(3) 和 feb(2) 的值,因此我们可以计算 feb(4) 的值。根据斐波那契数列的定义,第4个数应该是前两个数之和,即2+1=3。因此,feb(4) 的返回值为3。

现在,我们已经得到了 feb(4) 和 feb(3) 的值,因此我们可以计算 feb(5) 的值。根据斐波那契数列的定义,第5个数应该是前两个数之和,即3+2=5。因此,feb(5) 的返回值为5。

最后,我们在主函数中将 feb(5) 的返回值打印出来,结果为5。
因此,这段代码的执行过程可以总结如下:

调用 feb(5) 函数来计算斐波那契数列的第5个数。

feb(5) 函数内部调用 feb(4) 和 feb(3) 函数来计算斐波那契数列的第4个数和第3个数。

feb(4) 函数内部调用 feb(3) 和 feb(2) 函数来计算斐波那契数列的第3个数和第2个数。

feb(3) 函数内部调用 feb(2) 和 feb(1) 函数来计算斐波那契数列的第2个数和第1个数。

feb(2) 函数内部直接返回值1。

feb(1) 函数内部直接返回值1。

feb(3) 函数内部得到 feb(2) 和 feb(1) 的返回值后,计算斐波那契数列的第3个数为2。

feb(4) 函数内部得到 feb(3) 和 feb(2) 的返回值后,计算斐波那契数列的第4个数为3。

feb(5) 函数内部得到 feb(4) 和 feb(3) 的返回值后,计算斐波那契数列的第5个数为5。

主函数将 feb(5) 的返回值打印出来,结果为5。

おすすめ

転載: blog.csdn.net/weixin_39855998/article/details/130119487