目录
前言
递归函数指的是在函数定义中调用函数自身的过程。递归是一种常见的编程技巧,特别适合解决可以分解为相似子问题的问题,例如树结构的遍历、分治算法等。在编写递归函数时,需要注意正确地定义出口,以避免无限循环,确保递归能够结束。
递归函数的基本结构:
1.出口
2.自己调用自己
下面是一个递归函数的经典实例,用于计算阶乘
def factorial(n):
# 出口
if n == 0:
return 1
# 自己调用自己
else:
return n * factorial(n - 1)
# 计算 5 的阶乘
result = factorial(5)
print(result)
输出:
120
在这个例子中:
- 函数
factorial
是一个递归函数,它定义了两个情况:- 出口:当
n
等于 0 时,返回 1,这是递归的结束条件。 - 自己调用自己:当
n
大于 0 时,计算n
的阶乘,通过调用factorial(n - 1)
来实现递归。
- 出口:当
- 最终,递归函数在出口时结束递归,返回结果。
-
理解递归:理解递归的关键在于理解递归调用如何分解问题,并确保每一步向基本情况逼近。
用递归函数解决十大经典排序中的冒泡排序和快速排序
1.冒泡排序(Bubble Sort)
# 冒泡排序
def bubble_sort(arr, n):
# 出口
if n == 1:
return arr
# 一次冒泡操作:将当前最大的元素冒泡到正确的位置
for i in range(n - 1):
if arr[i] > arr[i + 1]:
# 如果相邻元素顺序错误,则交换它们
arr[i], arr[i + 1] = arr[i + 1], arr[i]
# 对剩余的 n-1 个元素递归调用冒泡排序
return bubble_sort(arr, n - 1)
# 示例用法:
arr = [3,44,38,5,47,15,36,26,27,2,46,4,19,59,48]
sorted_arr = bubble_sort(arr, len(arr))
print("Sorted array:", sorted_arr)
输出:
Sorted array: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 59]
解释:
-
函数
bubble_sort
:- 接收一个列表
arr
和一个整数n
,表示要排序的数组和数组的长度。 - 出口:当
n
等于 1 时,表示数组只有一个元素或者已经排序完成,直接返回数组arr
。 - 自己调用自己:
- 在每次调用中,通过一次遍历将当前最大的元素冒泡到正确的位置。
- 递归调用
bubble_sort
对剩余的n-1
个元素进行排序。
- 接收一个列表
-
排序过程:
- 在每次递归调用中,通过
for
循环遍历arr
到n-1
,如果发现相邻元素顺序错误,则交换它们。 - 每次递归调用完成后,当前最大的元素被冒泡到了正确的位置。
- 在每次递归调用中,通过
-
返回值:
- 最终递归到
n == 1
时,排序完成,函数返回已排序的数组arr
。
- 最终递归到
动图演示(图像来自网络)
2.快速排序(Quick Sort)
# 快速排序
def quick_sort(arr):
# 出口
if len(arr) <= 1:
return arr
# 选择基准元素(这里选择中间元素)
basis = arr[len(arr) // 2]
# 分割数组为小于基准、等于基准、大于基准的三部分
left = [x for x in arr if x < basis]
middle = [x for x in arr if x == basis]
right = [x for x in arr if x > basis]
# 递归排序左右两部分
return quick_sort(left) + middle + quick_sort(right)
# 示例用法:
arr = [3,44,38,5,47,15,36,26,27,2,46,4,19,59,48]
sorted_arr = quick_sort(arr)
print("Sorted array:", sorted_arr)
输出:
Sorted array: [3,44,38,5,47,15,36,26,27,2,46,4,19,59,48]
解释:
-
函数
quick_sort
:- 接收一个列表
arr
,表示要排序的数组。 - 出口:如果数组长度小于等于1,直接返回数组本身。
- 接收一个列表
-
排序过程:
- 选择基准元素:通常选择数组的中间元素作为基准basis。
- 分割数组:将数组分割为三部分:
left
:所有小于基准的元素;middle
:所有等于基准的元素;right
:所有大于基准的元素。
- 递归排序:
- 递归调用
quick_sort
对left
和right
进行排序。 middle
部分由于已经是有序的,不需要再排序,直接连接在结果中。
- 递归调用
-
返回值:
- 最终通过递归,将左部分、中间部分和右部分分别排序后合并起来,得到完全排序的数组。
动图演示(图像来自网络)