Python算法——递归思想

编程语言在构建程序时的基本操作有:内置数据类型操作、选择、循环、函数调用等,递归实际属于函数调用的一种特殊情况(函数调用自身),其数学基础是数学归纳法。递归在计算机程序设计中非常重要,是许多高级算法实现的基础

编写递归程序的几个要点:

1、终止条件:最简单情况(避免无限循环)

2、递归公式:相邻两次调用间的关系(递归算法核心)

3、忽略调用具体细节:假设所有调用都会达到终止条件(从思想上接受递归算法的关键)

4、效率:递归算法有时效率较低,可考虑其他更高效的实现方式(见问题5)

下面我们通过几个典型问题了解递归程序的的写法和思路:

问题1:求F(n)=1+2+3+...+n

也可用for循环实现,相比之下递归的代码更加简洁

从后往前:

def F(a):
    if len(a)==1:return(a[0])
    return(F(a[1:])+a[0])

或从前往后:

def FF(a):
    n = len(a)
    if n == 1:return(a[0])
    return (FF(a[:n-1])+a[n-1])

效果:

a=[1,4,6,9]
print(F(a))
>> 20

问题2:n条直线最多可以划分的平面个数?

首先举几个简单的例子,F(1) = 2,F(2) = 4,F(3) = 7

简单画个图就可以看出,每次划分增加1条直线,实际是在上次划分的基础上增加了n个交点,进而增加了n个平面

def F(n):
    if n == 1:return(2)
    return(F(n-1) + n)

问题3:求两个正整数的最大公约数

利用欧几里得算法:若p>q,则p和q的最大公约数等于q和p%q的最大公约数(证明思路:p和q的最大公约数等于p和p-q的最大公约数,也等于p和p-2q的公约数,以此类推直到p和p-nq即p%q)

终止条件:p被q整除,q=0,p即为所求(任何正整数都可被1整除,故一定能收敛)

def F(p,q):
    if q == 0:return p
    print(p,q)
    return F(q,p % q)
print(F(1440,408))
>> 1440 408
>> 408 216
>> 216 192
>> 192 24
>> 24

问题4:汉诺塔问题。把圆盘按大小顺序移到另一个圆盘上,每次只能移一个,小圆盘不能放大圆盘上边,如果有64个圆盘,需要挪多少次?

像这种问题如果生想的话估计会把脑细胞耗尽,索性我们有递归大法,可以忽略具体的实现细节:

终止条件:f(1)=1

递归公式:f(n)=2f(n-1)+1

def F(n):
    if n == 1:return 1
    return 2*F(n-1)+1

>>print(F(64))
>>18446744073709551615

问题5:斐波那契数列(1,1,2,3,5,8,13,21,34...)求和

def F(n):
    if n == 1 or n == 2:
        return 1
    return(F(n-1) + F(n-2))

但由于存在重复计算,此程序效率较低,实际开发中通常采用其他方式实现,详见:

斐波那契数列的5种Python写法

斐波那契数列的矩阵解法

问题6:编写merge(L1,L2)函数,将两个排好序的小列表合成一个排好序的大列表,如merge([1,2,4],[3,5])=[1,2,3,4,5]

merge()是归并排序算法中的关键函数,我们在这里用递归实现一下:

def merge(L1,L2):
    if len(L1) == 0:return(L2)
    if len(L2) == 0:return(L1)
    if L1[0]<L2[0]:
        return([L1[0]]+merge(L1[1:len(L1)],L2))
    else:
        return([L2[0]]+merge(L1,L2[1:len(L2)]))

>>print(merge([1,2,4],[3,5]))
>>[1,2,3,4,5]

当然merge()有许多其他的实现方法,大家可自行探索

掌握了递归思想后,我们就可以写出更加简洁、高效的程序了。在后续算法的学习中,要注意递归思想在不同条件下的体现,熟练运用

原文地址:https://www.cnblogs.com/cxc1357/p/10324179.html

时间: 2024-08-29 16:27:52

Python算法——递归思想的相关文章

算法—— 递归思想

#region 二叉树的先序遍历2 /// <summary>3  /// 二叉树的先序遍历4  /// </summary>5  /// <typeparam name="T"></typeparam>6  /// <param name="tree"></param>7          public void BinTree_DLR<T>(ChainTree<T>

Java算法——递归思想

描述递归(recursion):程序调用自身的编程技巧. 递归满足2个条件:1)有反复执行的过程(调用自身)2)有跳出反复执行过程的条件(递归出口) 递归与栈的关系下面演示的是求n的阶乘 int Factorial(int n){ if (n == 0) return 1; return n * Factorial(n - 1); } 常常听到 “递归的过程就是出入栈的过程”,这句话怎么理解?我们以上述代码为例,取 n=3,则过程如下: 第 1~4 步,都是入栈过程,Factorial(3)调用

Python算法 - 递归精解 - 汉诺塔问题

汉诺塔问题 题意 将A 柱子上的块转移到 C 上 条件1  -  每次只能转移一块 条件2  -  大块不能压小快 解析 概念原理 冰箱装大象问题 : 1. 打开冰箱 2. 放入大象 3. 关上冰箱 类比在 任何一个块 n 来说: 1. 把上面的块都移动好 2. n 块移动过去 3. 之前上面的块在放在 n 块上面 简化问题, 考虑 123块的移动, 可以考虑成我想移动 3 . 必然要移动12 同理 我想移动 2, 必然要移动 1 , 即关系为 f(3) ---> f(2) ---> f(1)

python算法之递归思想

#递归思想#基本原理:函数内部调用函数本身,注意:至少有一个终止条件#例1.斐波那契数列def fib(x): if x==1 or x==2: return 1 else: return fib(x-1) + fib(x-2)def fibList(x): fibList = [] for i in range(x): fibList.append(fib(i+1)) return fibListprint(fibList(9)) #例2.n的阶乘(n*(n-1)*(n-2)*...2*1)d

算法之递归思想

树的遍历的实现就是典型的递归思想. /* * description:树的遍历示例,递归 * 访问顺序: * 前序: 当前节点 - 左子树 - 右子树 * 中序: 左子树 - 当前节点 - 右子树 * 后序: 左子树 - 右子树 - 当前节点 * * writeby: nick * date: 2012-10-22 23:56 */ #include <iostream> using namespace std; struct node { int item; node *l, *r; nod

Python算法:推导、递归和规约

Python算法:推导.递归和规约 注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心知识:Induction(推导).Recursion(递归)和Reduction(规约),这是原书的重点和难点部分 正如标题所示,本节主要介绍下面三部分内容: • Reduction means transforming one problem to another. We normally red

区域增长算法的设计与实现(递归思想和堆栈数据结构)

程序员:左正康           发表时间:2013年12月16日 0:56    代号:与老鼠共处一室的日子 算法设计思想:算法中主要有2个函数,分别是CreateSeed函数和Decide函数,CreateSeed函数:创建种子点:Decide函数:决定连通点是否进入生长区域,进入生长区域的连通点作为下一个种子点递归调用CreateSeed函数,直到生长区域不再长大,结束递归. 程序测试展示:

python 算法

在Python实践中,我们往往遇到排序问题,比如在对搜索结果打分的排序(没有排序就没有Google等搜索引擎的存在),当然,这样的例子数不胜数.<数据结构>也会花大量篇幅讲解排序.之前一段时间,由于需要,我复习了一下排序算法,并用Python实现了各种排序算法,放在这里作为参考. 最简单的排序有三种:插入排序,选择排序和冒泡排序.这三种排序比较简单,它们的平均时间复杂度均为O(n^2),在这里对原理就不加赘述了.贴出来源代码. 插入排序: def insertion_sort(sort_lis

第二篇 递归思想

今天说说递归思想,在我们编码时,有的时候递归能够让我们的算法更加通俗易懂,并且代码量也是大大的减少.比如我先前的系列中说到了 关于树的“先序,中序和后序”遍历,那么看看用递归来描叙这个问题是多少的简洁,多么的轻松. 1 #region 二叉树的先序遍历 2 /// <summary> 3 /// 二叉树的先序遍历 4 /// </summary> 5 /// <typeparam name="T"></typeparam> 6 /// &