递归函数是计算机编程中常用的一种函数,它可以让程序更加简洁和优美。其实,递归函数就是函数自己调用自己,然后根据一些条件,结束调用或继续递归调用。让我们来看看一些妙趣横生的递归函数例子,看看它们如何让你在代码世界中信手拈来。
1. 阶乘函数
先来看一个经典的例子:阶乘函数。阶乘函数是数学中经常用到的函数,计算一个正整数n的阶乘的值,就是n的所有正整数相乘。例如:5的阶乘为5×4×3×2×1=120。 我们可以用递归函数来计算阶乘,如下:
```python
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
```
我们来解析一下这个函数的执行过程。当调用factorial(5)时,它会执行以下步骤:
1. 判断n是否等于1,因为n不等于1,所以第一个分支不成立,执行else分支。
2. 返回n * factorial(n-1)的值。
3. 将n减1得到4,递归调用factorial(4)。
4. 判断n是否等于1,因为n不等于1,所以第一个分支不成立,执行else分支。
5. 返回n * factorial(n-1)的值。
6. 将n减1得到3,递归调用factorial(3)。
7. 判断n是否等于1,因为n不等于1,所以第一个分支不成立,执行else分支。
8. 返回n * factorial(n-1)的值。
9. 将n减1得到2,递归调用factorial(2)。
10. 判断n是否等于1,因为n不等于1,所以第一个分支不成立,执行else分支。
11. 返回n * factorial(n-1)的值。
12. 将n减1得到1,递归调用factorial(1)。
13. 判断n是否等于1,因为n等于1,所以第一个分支成立,返回1。
14. 得到返回值1,将其乘以n,即5,得到5的阶乘的值120,返回该值。
因此,调用factorial(5)最终的返回值为120。这个递归函数的执行过程惊奇富有趣味性,不同于传统的循环计算阶乘,更加优美简洁。
2. Fibonacci数列
Fibonacci数列是一个很有意思的数列,它是由意大利数学家Fibonacci提出的,是一个无限数列。该数列的前两项为0和1,后续各项都是由前两项之和得到。即:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …
我们可以用递归函数来生成Fibonacci数列,如下:
```python
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
```
当调用fibonacci(5)时,它会执行以下步骤:
1. 判断n是否等于0,因为n不等于0,所以第一个分支不成立。
2. 判断n是否等于1,因为n不等于1,所以第二个分支不成立。
3. 返回fibonacci(n-1) + fibonacci(n-2)的值。
4. 将n减1得到4,递归调用fibonacci(4)。
5. 判断n是否等于0,因为n不等于0,所以第一个分支不成立。
6. 判断n是否等于1,因为n不等于1,所以第二个分支不成立。
7. 返回fibonacci(n-1) + fibonacci(n-2)的值。
8. 将n减1得到3,递归调用fibonacci(3)。
9. ……
10. 判断n是否等于0,因为n等于0,所以第一个分支成立,返回0。
11. 判断n是否等于0,因为n等于1,所以第二个分支成立,返回1。
12. 得到返回值1和返回值0,将其相加,得到返回值1,返回该值。
因此,调用fibonacci(5)最终的返回值为5,即Fibonacci数列中第5个数值。
3. 排列组合
排列组合是组合数学中的一个重要概念,有时也称为选择问题。对于一个集合,从中选取一些元素排列组合,这样的结果有多少种?我们可以用递归函数来计算排列组合,如下:
```python
def parmutation(n, k):
if k == 0:
return 1
else:
return n * parmutation(n-1, k-1)
def combination(n, k):
if k == 0:
return 1
else:
return combination(n-1, k-1) * n // k
```
当调用combination(5, 3)时,它会执行以下步骤:
1. 判断k是否等于0,因为k不等于0,所以第一个分支不成立。
2. 返回combination(n-1, k-1) * n // k的值。
3. 将n减1得到4,递归调用combination(4, 2)。
4. 判断k是否等于0,因为k不等于0,所以第一个分支不成立。
5. 返回combination(n-1, k-1) * n // k的值。
6. 将n减1得到3,递归调用combination(3, 1)。
7. 判断k是否等于0,因为k不等于0,所以第一个分支不成立。
8. 返回combination(n-1, k-1) * n // k的值。
9. 将n减1得到2,递归调用combination(2, 0)。
10. 判断k是否等于0,因为k等于0,所以第一个分支成立,返回1。
11. 得到返回值1,将其乘以n,即5,得到5个元素中选取3个元素的组合数值10,返回该值。
因此,调用combination(5, 3)最终的返回值为10。
4. 等差数列求和
等差数列是一个常见的数列,其一般形式为a(n) = a(1) + (n-1)d,其中a(1)是首项,d是公差。我们可以用递归函数来求等差数列的和,如下:
```python
def arithmetic_sum(n, a1, d):
if n == 1:
return a1
else:
return a1 + arithmetic_sum(n-1, a1+d, d)
```
当调用arithmetic_sum(5, 1, 2)时,它会执行以下步骤:
1. 判断n是否等于1,因为n不等于1,所以第一个分支不成立。
2. 返回a1 + arithmetic_sum(n-1, a1+d, d)的值。
3. 将n减1得到4,递归调用arithmetic_sum(4, 3, 2)。
4. 判断n是否等于1,因为n不等于1,所以第一个分支不成立。
5. 返回a1 + arithmetic_sum(n-1, a1+d, d)的值。
6. 将n减1得到3,递归调用arithmetic_sum(3, 5, 2)。
7. ……
8. 判断n是否等于1,因为n等于1,所以第一个分支成立,返回a1的值,即1。
9. 得到返回值1,将其加上各项之和即等差数列1,3,5,7,9的和为25,返回该值。
因此,调用arithmetic_sum(5, 1, 2)最终的返回值为25。
5. 二分查找
二分查找是一种高效的查找算法,也称为折半查找。它的基本思想就是在有序数列中查找某一特定元素,每次通过将待查区域一分为二,依次缩小搜索范围,直到找到目标元素。我们可以用递归函数来实现二分查找算法,如下:
```python
def binary_search(arr, low, high, target):
if high >= low:
mid = (high + low) // 2
if arr[mid] == target:
return mid
elif arr[mid] > target:
return binary_search(arr, low, mid-1, target)
else:
return binary_search(arr, mid+1, high, target)
else:
return -1
```
当调用binary_search([2, 3, 4, 7, 10], 0, 4, 7)时,它会执行以下步骤:
1. 判断high是否大于等于low,因为high等于4,low等于0,所以第一个分支成立。
2. 计算mid的值为2,arr[mid]的值为4,不等于目标元素7,跳过第3个分支。
3. 判断arr[mid]是否大于目标元素target,因为arr[mid]小于目标元素7,所以跳过第4个分支。
4. 递归调用binary_search(arr, mid+1, high, target)。
5. 判断high是否大于等于low,因为high等于4,mid+1等于3,所以第一个分支成立。
6. 计算mid的值为3,arr[mid]的值为7,等于目标元素7,返回mid的值3。
因此,调用binary_search([2, 3, 4, 7, 10], 0, 4, 7)最终的返回值为3,表示目标元素在有序数列中的位置。
递归函数是计算机编程中的一个重要概念,熟练掌握递归函数的运行流程和优点颇具益处。从以上的例子我们可以看出,递归函数能够让程序更加简洁,代码更具可读性。希望读者在今后的程序开发中,能够充分运用递归函数,让自己的代码更加优美、显得更加灵活和高效。