递归算法(一)递归概念与思路

递归的概念

程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

我会写先介绍递归的基本思想,然后再以后的文章中介绍一下递归的衍生算法,比如:回溯算法、分治法、DFS等。

设计递归的思路

通常我们一提到递归就立马想到了递归的两个重要部分:终止条件与循环部分。递归的设计思路是很像我门做数学题:根据已知条件找规律,利用递推式求解未知变量。但是我们作为开发者面对的是计算机,我们需要用程序语言设计出递归的算法去解决问题。下面是递归设计的四个重要要素:

  1. 接收的参数
  2. 返回值
  3. 终止条件
  4. 递归拆解:如何递归下一层

递归实例

俗话说的好:”孰能生巧“,光说不练,假把式。光用文字去解释递归如何如何让地去设计,倒不如多花时间从易到难循序渐进做大量练习,通过大量的练习,去寻找其中的规律。

实例1:n的阶乘

# 递归实现N的阶乘
def fact_resursion(n):# 终止条件if n==1:return 1else:return n*fact_resursion(n-1) # 循环部分print(fact_resursion(5))

运行结果:120

实例2:斐波那契数列

这里简单的解释一下斐波那契数列:F(0) = 0 , F(1) = 1
F(N) = F(N-1) + F(N-2) , N>1 数列前几项如下:
0 1 1 2 3 5 8 13 …

# 递归实现斐波那契数列F(N)的计算
def fun(n):# 终止条件if n <=1:return nelse:return fun(n-1) + fun(n-2) # 循环部分
print(fun(8))

运行结果:21

实例3:小青蛙跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

解析:
每次跳的时候,小青蛙可以跳一个台阶,也可以跳两个台阶,也就是说,每次跳的时候,小青蛙有两种跳法。
第一种跳法:第一次我跳了一个台阶,那么还剩下n-1个台阶还没跳,剩下的n-1个台阶的跳法有f(n-1)种。

第二种跳法:第一次跳了两个台阶,那么还剩下n-2个台阶还没,剩下的n-2个台阶的跳法有f(n-2)种。

所以,小青蛙的全部跳法就是这两种跳法之和了,即 f(n) = f(n-1) + f(n-2)。至此,等价关系式就求出来了。

def func(n):if n<=2:return nreturn func(n-1) + func(n-2)
print(func(4))

运行结果:5

实例3:列表反转

# 递归实现列表反转
def rev(alist,left,right):if left >= right: # 终止条件returnrev(alist,left+1,right-1)# 循环部分alist[left],alist[right] = alist[right],alist[left]
alist = [1,2,3,4,5,6]
left = 0
right = len(alist) - 1
rev(alist,left,right)
print(alist)

运行结果:[6, 5, 4, 3, 2, 1]

实例4:字符串反转

注意:有人可能会觉得字符串反转和列表反转难道不是一样的吗?
如果用反转列表的方法去反转字符串会出现一下错误:

TypeError: ‘str’ object does not support item assignment

在python中,字符串是不可变对象,不能通过下标的方式直接赋值修改。同样的不可变对象还有:数字、字符串和元组。

直观一点举个小例子:
s = “abcd”
x = s[2]
print(x) => ‘c’

但是直接赋值:s[2] = ‘h’ 却会报错

# 递归实现字符串的反转
def rvs(s):# 终止条件if len(s) == 1:return selse:return rvs(s[1:])+s[0]  # 循环部分
print(rvs("abcdefg"))

运行结果:gfedcba

实例5:链表反转

注意:因为实现链表反转需要自己创建一个链表类和方法,比较麻烦我们就直接用leetcode的206题:链表反转。
在这里插入图片描述
代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: ListNode) -> ListNode:# 方法一:双指针# pre,cur = None,head# while cur:#     next = cur.next#     cur.next = pre#     pre = cur#     cur = next# return pre# 方法二: 递归# 边界条件   和    终止条件if head == None or head.next == None:return head# 循环部分 newhead = self.reverseList(head.next)head.next.next = headhead.next = Nonereturn newhead

实例6:汉诺塔游戏

汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?

假设三根柱子分别为:A,B,C。A柱子上有n个盘子,B,C为空。请问每一步该如何移动?

# 汉诺塔
count = 1
n = 4
def move(n,a,b,c):global countif n == 1:print(count,":",a, '-->', c)count += 1else:move(n-1, a, c, b)print(count,":",a, '-->', c)count += 1move(n-1, b, a, c)        
print(f'把A柱子的{n}个盘子全部移到C柱子的顺序为:')
move(n, 'A', 'B', 'C')

运行结果:
把把A柱子的4个盘子全部移到C柱子的顺序为:
1 : A --> B
2 : A --> C
3 : B --> C
4 : A --> B
5 : C --> A
6 : C --> B
7 : A --> B
8 : A --> C
9 : B --> C
10 : B --> A
11 : C --> A
12 : B --> C
13 : A --> B
14 : A --> C
15 : B --> C

例子7:科赫雪花

利用python的turtle库绘制科赫雪花,如下图所示:
在这里插入图片描述

# 科赫雪花
# -*- coding: utf-8 -*-
import turtle
def koch(size,n):"""函数koch用递归思想绘制一段N阶曲线"""if n == 0:turtle.fd(size)     #递归基例(终止条件),0阶曲线即为一条直线else:for i in [0,60,-120,60]:    #通过改变方向,绘制四条线段turtle.left(i)koch(size/3,n-1)	# 循环部分
def main():"""定义main函数调用koch""" turtle.setup(600,600)turtle.penup()turtle.goto(-250,100)turtle.pendown()turtle.pensize(2)n = 3for i in range(0,3):koch(500,n)turtle.right(120)turtle.hideturtle()turtle.done()
main()

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洛谷 P1706 P1036 -小试牛刀

题目1&#xff1a; 题目描述 输出自然数 1 到 n 所有不重复的排列,即 n 的全排列&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 n。 输出格式 由 1∼n1∼n1∼n 组成的所有不重复的数字序列&#xff0c;每行一个序列。 每个数字保留 5 个…

理解ASP.NET Core中的中间件

中间件是ASP.NET Core的一个重要特点&#xff0c;ASP.NET Core应用程序之所以能够灵活地处理各种各样的请求&#xff0c;完成都是由于中间件&#xff0c;那么它究竟是怎么一回事呢&#xff1f;一、理解中间件ASP.NET Core的一个主要特点是中间件&#xff08;Middleware&#xf…

XGBoost-原理推导(上)

XGBoost简介 XGBoost&#xff08;eXtreme Gradient Boosting&#xff09;是华盛顿大学博士陈天奇创造的一个梯度提升&#xff08;Gradient Boosting&#xff09;的开源框架。至今可以算是各种数据比赛中的大杀器&#xff0c;被大家广泛地运用。 之前的文章我已经介绍了GBDT&a…

redis深度历险_Redis的数据结构(内存具体怎么优化的)

上一篇我们讲解了Redis中SDS的组成以及优势&#xff0c;这一篇我们讨论下Redis中的Hash数据类型是怎么构成的呢&#xff1f;Java中存在HashMap和HashTable的数据类型。而Hash的数据结构可以近似于HashTable&#xff0c;依据数组链表的形式构成。在Redis中&#xff0c;Hash在元素…

.NET Core开发实战(第19课:日志作用域:解决不同请求之间的日志干扰)--学习笔记...

19 | 日志作用域&#xff1a;解决不同请求之间的日志干扰开始之前先看一下上一节的代码// 配置的框架 var configBuilder new ConfigurationBuilder(); configBuilder.AddCommandLine(args); configBuilder.AddJsonFile("appsettings.json", optional: false, reloa…

递归算法(二)-分治法

分治法 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题&#xff0c;这些子问题相互独立且与原问题性质相同。求出子问题的解&#xff0c;就可得到原问题的解。即一种分目标完成程序算法&#xff0c;简单问题可用二分法完成。 分治法解题的一般步骤&#…

自适应滤波器在matlab仿真的程序_电气信息类专业课程之matlab系统仿真 第五章 BPSK通信系统(3)...

继续讲解&#xff01;上一篇文章提出了那么多问题&#xff0c;不知道大家是否能回答上来啊&#xff1f;如果回答不了&#xff0c;有没有去问问度娘呢&#xff1f;程序写完了&#xff0c;回想了一下辅导2017届学生毕业设计的过程&#xff0c;那是真累。我要求他们在现有程序基础…

阿捷外传之Git代码统计:DotNetCore + PowerBI 实现Git仓库日志分析

前言2020年3月初春&#xff0c;虽然春节已经过去一个多月&#xff0c;大街上还未恢复往年的热闹。由于春节前夕突然降临的冠状病毒&#xff0c;导致很多员工无法回到城市复工。春节之后&#xff0c;阿捷所在的公司考虑到复工带来的风险&#xff0c;通知所有员工以远程的方式在家…

递归算法(三)- 回溯法Backtracking

回溯法 回溯法Backtracking&#xff08;找所有的可能&#xff09;递归&#xff1a; 类似枚举&#xff0c;一层一层向下递归&#xff0c;尝试搜索答案。找到答案&#xff1a; > 返回答案&#xff0c;并尝试别的可能未找到答案&#xff1a; > 返回上一层递归&#xff0c;…

一个全栈式的应用集成平台,打破“信息孤岛”

源宝导读&#xff1a;随着企业数字化进程的逐渐深入&#xff0c;企业存在大量的异构系统&#xff0c;各个系统之间信息传输、资源利用困难。本文将介绍明源云ERP为了打破这种“信息孤岛”&#xff0c;而进行的思考与实践。一、前言随着企业信息化进程的逐步深入&#xff0c;互联…

【朝夕技术专刊】Core3.1WebApi_Filter多种注册方式支持依赖注入

欢迎大家阅读《朝夕Net社区技术专刊》第5期我们致力于.NetCore的推广和落地&#xff0c;为更好的帮助大家学习&#xff0c;方便分享干货&#xff0c;特创此刊&#xff01;很高兴你能成为忠实读者&#xff0c;文末福利不要错过哦&#xff01;01PARTCoreFilter多种注册方式在上一…

SQL(一)- 数据库介绍与基础操作

数据库介绍 一、常用的数据库分为两大类&#xff1a; 关系型数据库非关系型数据库&#xff08;NoSql&#xff09; 关系型数据库 概念&#xff1a;是建立在关系模型基础上的数据库&#xff0c;借助于集合代数等数学概念和方法来处理数据库中的数据。 关系型数据库的优势&am…

opencv +数字识别

现在很多场景需要使用的数字识别&#xff0c;比如银行卡识别&#xff0c;以及车牌识别等&#xff0c;在AI领域有很多图像识别算法&#xff0c;大多是居于opencv 或者谷歌开源的tesseract 识别.由于公司业务需要&#xff0c;需要开发一个客户端程序&#xff0c;同时需要在xp这种…

SQL(二)- 基础查询语句

简单的查询语句&#xff08;DQL&#xff09; 下面我们正式来学习查询语句&#xff0c;下面所有查询用到的表均为前面提到的三张表&#xff1a; 员工表中的数据&#xff1a; 部门表中的数据&#xff1a; 薪资表中的数据&#xff1a; 基本查询语句的语法&#xff1a; sele…

SQL(三)- 连接查询

连接查询概念 一、什么是连接查询&#xff1f; 在实际开发中&#xff0c;大部分的情况下都不是从单张表中查询数据&#xff0c;一般都是多张表联合查询最终取出最终结果。在实际再发中&#xff0c;一般一个业务都会对应多张表&#xff0c;比如学生和班级&#xff0c;最起码两…

远程办公也可以很高效

题图&#xff1a;我的站立办公环境因为疫情&#xff0c;全中国人民都过了一个难忘的春节&#xff0c;而身在武汉的我&#xff0c;更是没有出家门半步&#xff0c;坚决做到不过国家添乱。从开始的2月14到后来的2月20日&#xff0c;再到现在的3月10日&#xff0c;官方发布的复工日…

SQL(四) - 子查询和union以及limit分页

子查询概念 什么是子查询&#xff1f;子查询都可以出现在哪里&#xff1f; select语句当中嵌套select语句&#xff0c;被嵌套的select语句是子查询。 子查询可以出现在哪里&#xff1f; select..(select). from..(select). where..(select).1.where子句中使用子查询 案例&a…

ASP.NET Core中的Http缓存

ASP.NET Core中的Http缓存Http响应缓存可减少客户端或代理对 web服务器发出的请求数。响应缓存还减少了 web服务器生成响应所需的工作量。响应缓存由 Http请求中的 header控制。而 ASP.NETCore对其都有相应的实现&#xff0c;并不需要了解里面的工作细节&#xff0c;即可对其进…

SQL(五) - 表的创建以及操作

创建表 建表语句的语法格式&#xff1a; create table 表名(字段名1 数据类型,字段名2 数据类型,字段名3 数据类型,....);MySql常用数据类型 BLOB 二进制大对象&#xff08;存储图片、视频等流媒体信息&#xff09; Binary Large OBject &#xff08;对应java中的Object&…

Istio 2020 年 Roadmap——一切为了商用

原文地址&#xff1a;https://preliminary.istio.io/zh/blog/2020/tradewinds-2020/&#xff0c;由 ServiceMesher 社区翻译。Istio 解决了人们在运行微服务时遇到的实际问题。甚至早期的预发行版本就已经可以帮助用户诊断其体系架构中的延迟&#xff0c;提高服务的可靠性以及透…