前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

递归

原创
作者头像
ruochen
修改于 2021-05-14 02:02:33
修改于 2021-05-14 02:02:33
8640
举报

@toc

递归

递归的算法思想

  • 基本思想 - 把一个问题划分为一个或多个规模更小的子问题,然后用同样的方法解规模更小的子问题
  • 递归算法的基本设计步骤 - 找到问题的初始条件(递归出口),即当问题规模小到某个值时,该问题变得很简单,能够直接求解 - 设计一个策略,用于将一个问题划分为一个或多个一步步接近递归出口的相似的规模更小的子问题 - 将所解决的各个小问题的解组合起来,即可得到原问题的解

设计递归算法需要注意以下几个问题

  • 如何使定义的问题规模逐步缩小,而且始终保持同一问题类型?
  • 每个递归求解的问题规模如何缩小?
  • 多大规模的问题可作为递归出口?
  • 随着问题规模的缩小,能到达递归出口吗?

递归设计实例

1. 计算 f(n) = 2<sup>n</sup>

代码语言:txt
AI代码解释
复制
f(n) = 2 × 2<sup>n-1</sup> = 2 × f(n-1)
代码语言:txt
AI代码解释
复制
f(1) = 2<sup>1</sup> = 2

Program

f(n)

  1. if n=0 then return 1
  2. else return 2 * f(n-1)

2. Hanoi问题

  1. 将前n-1个圆盘从A柱借助于C搬到B柱
  2. 将最后一个圆盘直接从A柱搬到C柱
  3. 将n-1个圆盘从B柱借助于A柱搬到C柱
代码语言:txt
AI代码解释
复制
Hanoi(n, A, B, C)
代码语言:txt
AI代码解释
复制
	if n=1 then move(1, A, C)
代码语言:txt
AI代码解释
复制
	else
代码语言:txt
AI代码解释
复制
		Hanoi(n-1, A, C, B)
代码语言:txt
AI代码解释
复制
		move(1, A, C)
代码语言:txt
AI代码解释
复制
		move(n-1, B, A, C)

T(n) = 2T(n-1) + 1

T(1) = 1

3. Selection sort

  • 基本思想 - 把所有牌摊开,放在桌上,伸出左手,开始为空,准备拿牌 - 将桌上最小额牌拾起,并把它插到左手所握牌的最右边 - 重复上一步,直到桌上的所有牌都拿到你的左手上,此时左手上所握得牌便是排好序的牌
代码语言:txt
AI代码解释
复制
SelectionSort(i)
代码语言:txt
AI代码解释
复制
	if i >= n then return 0
代码语言:txt
AI代码解释
复制
	else
代码语言:txt
AI代码解释
复制
		k = i
代码语言:txt
AI代码解释
复制
		for j <- i+1 to n do
代码语言:txt
AI代码解释
复制
			if A[j] < A[k] then 
代码语言:txt
AI代码解释
复制
				k <- j
代码语言:txt
AI代码解释
复制
		if k != i then A[i] <-> A[k]
代码语言:txt
AI代码解释
复制
		SelectionSort(i+1)

T(n) = T(n-1) + n

T(1) = 1

Java代码实现

代码语言:txt
AI代码解释
复制
package sort;

import java.util.Arrays;

public class RecursiveSelectionSort {

	public static void main(String[] args) {
		double[] list = {3, 1, 5, 7, 2};
		sort(list);
		/*
		for (int i = 0; i < list.length; i ++)
			System.out.print(list[i]+"    ");
		*/
		System.out.println(Arrays.toString(list));
	}
	
	public static void sort(double[] list) {
		sort(list, 0, list.length-1);
	}
	
	public static void sort(double[] list, int low, int high) {
		if (low < high) {
			double currentMin = list[low];
			int currentMinIndex = low;
			
			for (int i = low+1; i <= high; i++) {
				if (currentMin > list[i]) {
					currentMin = list[i];
					currentMinIndex = i;
				}
			}
			
			list[currentMinIndex] = list[low];
			list[low] = currentMin;
			
			sort(list, low+1, high);
		}
	}
}

4. 生成排列

  • 问题是生成{1, 2, ...., n}的所有n!排序
想法1: 固定位置放元素
  • 假设我们能够生成n-1个元素的所有排列,我们可以得到如下算法: - 生成元素{2, 3, ...., n}的所有排列,并且将元素 1 放到每个排列的开头 - 接着,生成元素{1, 3, ...., n}的所有排列,并且将元素 2 放到每个排列的开头 - 重复这个过程,直到元素{2, 3, ...., n-1}的所有排列都产生,并将元素 n 放到每个排列的开头
代码语言:txt
AI代码解释
复制
		GeneratingPerm1()
代码语言:txt
AI代码解释
复制
			for j <- 1 to n do
代码语言:txt
AI代码解释
复制
				P[j] <- j
代码语言:txt
AI代码解释
复制
			Perm1()
代码语言:txt
AI代码解释
复制
		Perm1(m)
代码语言:txt
AI代码解释
复制
			if m = n then output P[1...n]
代码语言:txt
AI代码解释
复制
			else
代码语言:txt
AI代码解释
复制
				for j <- m to n do
代码语言:txt
AI代码解释
复制
					P[j] <-> P[m]
代码语言:txt
AI代码解释
复制
					Perm1(m+1)
代码语言:txt
AI代码解释
复制
					P[j] <-> P[m]
代码语言:txt
AI代码解释
复制
	T(n) = nT(n-1) + n
想法2: 固定元素找位置
  • 首先,我们把 n 放在位置P1上,并且用子数组P2...n 来产生前 n-1 个数的排列
  • 接着,我们将 n 放在P2上,并且用子数组P1和P3...n来产生前 n-1 个数的排列
  • 然后,我们将 n 放在P3上,并且用子数组P1...2和P4...n来产生前 n-1 个数的排列
  • 重复上述过程直到我们将 n 放在Pn上,并且用子数组P1...n-1来产生前 n-1 个数的排列
代码语言:txt
AI代码解释
复制
	GeneratingPerm2()
代码语言:txt
AI代码解释
复制
		for j<-1 to n do
代码语言:txt
AI代码解释
复制
			p[j]<-0
代码语言:txt
AI代码解释
复制
			Perm2(n)
代码语言:txt
AI代码解释
复制
	Perm2(m)
代码语言:txt
AI代码解释
复制
		if m = 0 then ouput P[1 ... n]
代码语言:txt
AI代码解释
复制
		else
代码语言:txt
AI代码解释
复制
			for j<-1 to n do
代码语言:txt
AI代码解释
复制
				if P[j]=0 then
代码语言:txt
AI代码解释
复制
					P[j]<-m
代码语言:txt
AI代码解释
复制
					Perm2(m-1)
代码语言:txt
AI代码解释
复制
					P[j]<-0

递归方程求解

公式法

  • 对于下列形式的递归方程 - T(n) = aT(n/b) + f(n) - 其中 a >= 1, b > 1是常数,f(n)是一个渐进正函数,可以使用公式法(Master Method) 方便快捷地求得递归方程地解
  • 将一个规模为n的问题划分成a个规模为n/b的子问题,其中a和b为正常数,分别递归地解决a个子问题,解每个子问题所需时间为T(n/b),划分原问题和合并子问题的解所需的时间由f(n)决定
  • 令 a >= 1和b > 1 是常数,f(n)是一个正函数,T(n)满足 - T(n) = aT(n/b) + f(n) - 其中n/b表示n/b或者n/b, 则T(n)有如下三种情况的渐进界 1. if f(n) = O(n<sup>log<sub>b</sub>a-$\varepsilon$</sup>), for some constant $\varepsilon$ > 0, then T(n) = $\Theta$(n<sup>log<sub>b</sub>a</sup>) 2. if f(n) = $\Theta$(n<sup>log<sub>b</sub>a</sup>), then T(n) = $\Theta$(n<sup>log<sub>b</sub>a</sup> lgn) 3. if f(n) = $\Omega$(n<sup>log<sub>b</sub>a+$\varepsilon$</sup>), for some constant $\varepsilon$ > 0, and if af(n/b) &\leq& cf(n) for some c < 1 and all sufficiently large n, then T(n) = $\Theta$(f(n))

案例

  • T(n) = 9T(n/3) + n, a = 9, b = 3, f(n) = n, and n<sup>log<sub>b</sub>a</sup> = n<sup>log<sub>3</sub>9</sup> = n<sup>2</sup> f(n) = O(n<sup>log<sub>b</sub>a-$\varepsilon$</sup>) = O(n<sup>log<sub>3</sub>9-1</sup>) T(n) = $\Theta$(n<sup>2</sup>)
  • T(n) = T(2n/3) + 1, a = 1, b = 3/2, f(n) = 1, and n<sup>log<sub>b</sub>a</sup> = n<sup>log<sub>3/2</sub>1</sup> = n<sup>0</sup> = 1 f(n) = $\Theta$(n<sup>log<sub>b</sub>a</sup>) = $\Theta$(1) T(n) = $\Theta$(lgn)
  • T(n) = T(n-1) + n, f(n) = n, a = b = 1, 不可应用此方法

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
javascript入门笔记7-计时器
该文介绍了JavaScript中常用的计时器,包括setTimeout、setInterval和clearTimeout。每种计时器都有其独特的用法和功能。在文章中还提供了两个示例,一个是使用setTimeout实现的无穷循环计数器,另一个是使用setInterval和clearTimeout实现的取消计时器。
方志朋
2017/12/29
1.2K3
第46天:setInterval与setTimeout的区别
js的setTimeout方法用处比较多,通常用在页面刷新了、延迟执行了等等。今天对js的setTimeout方法做一个系统地总结。
半指温柔乐
2018/09/11
1.4K0
JS设置定时器_js设置定时器
每个JS定时器产生时会被系统分配一个id,这个id是正整数,而且一个页面里面的定时器id不重复,我们能用一个变量接收这个id,但是如果重复执行一条接收创建语句,那么你只能接收到最新创建的定时器的id,之前创建的定时器的id会被覆盖,但是定时器数量在增加,这就会导致界面一些功能错乱,解决方法就是在重复按开始按钮时,如果已经有了一个定时器那么就不执行语句,我列出了错误代码和三种解决方法,可以解决定时器重复创建问题。 ps:定时器id的配发是递增的,从1开始累加,但是有一个小细节,就是当你在一次页面运行的过程中,打个比方,你创建了第五个定时器,它的id为5,然后你把它销毁,再创建一个定时器,那么这个定时器的编号会是6,而不是5,5号id是不会因为第五个定时器器的销毁而可以被再次使用。
全栈程序员站长
2022/11/15
30.3K0
js中setTimeout的用法和JS计时器setTimeout与setInterval方法的区别和confirm方法
setTimeout()在js类中的使用方法 setTimeout (表达式,延时时间) setTimeout(表达式,交互时间) 延时时间/交互时间是以豪秒为单位的(1000ms=1s) setTimeout 在执行时,是在载入后延迟指定时间后,去执行一次表达式,仅执行一次 setTimeout 在执行时,它从载入后,每隔指定的时间就执行一次表达式 1,基本用法: 执行一段代码: var i=0; setTimeout("i+=1;alert(i)",1000); 执行一个函数: var i=0
用户7657330
2020/08/14
3.2K0
我之理解---计时器setTimeout 和clearTimeout
今天在写个图片切换的问题 有动画滞后的问题,才动手去查setTimeout 和clearTimeout。之前写的图片播放器也有类似的问题,有自动start按钮 和stop按钮, 其他都正常,问题出在每次多次快速的点击start按钮时,图片播放的速度会变块很多,而且没有规律。当时也没有去想这个问题,直到今天遇到了类似的问题 才决定去一探究竟。 列举个简单累加例子: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="te
大当家
2018/06/28
1.1K0
超级玛丽HTML5源代码学习-----(三)
定义和用法 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。 setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。 语法 setInterval(code,millisec[,"lang"]) 参数 描述 code 必需。要调用的函数或要执行的代码串。 millisec 必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。 返回值 一个可以传递给 Window.clearInterval() 从而取消对 code 的周期性执行的值。
wust小吴
2022/03/03
1.3K0
js中settimeout()的用法详解_js中setattribute
setTimeout与setTimeInterval均为window的函数,使用中顶层window一般都会省去,这两个函数经常稍不留神就使用错了。
全栈程序员站长
2022/11/09
15.4K0
js对象(BOM部分/DOM部分)
JS总体包括ECMAScript,DOM,BOM三个部分,但是能够和浏览器进行交互的只有DOM和BOM,那么到底什么是DOM和BOM呢
全栈程序员站长
2022/07/21
4.4K0
js对象(BOM部分/DOM部分)
js中settimeout和setInterval区别_JavaScript set
注:调用过程中,可以使用clearTimeout(id_of_settimeout)终止
全栈程序员站长
2022/11/09
2K0
js"发送验证码"倒计时效果!
 发送验证码倒计时很简单,昨天作的,今天贴出来,作个记录,也请朋友看看,可以不优化一下! <input type="button" id="fsyzm" onclick="timedCount()" class="btn5" value="发送校验码" /> <script type="text/javascript"> var Time=3, t; var c=Time function timedCount(){ document.getElementBy
deepcc
2018/05/16
1.4K0
js倒计时代码最简单的(js倒计时10秒代码)
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/127705.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/25
10.5K0
定时器setTimeout和setInterval的简单应用
本文简单利用定时器setTimeout和setInterval举了两个小栗子:定时炸弹和1-100递增
全栈程序员站长
2022/11/09
6190
第85节:Java中的JavaScript
后代选择器: 选择器1 选择器2 子元素选择器:选择器1 > 选择器2 选择器分组: 选择器1,选择器2,选择器3{} 属性选择器:选择器[属性名称='属性值']
达达前端
2019/07/03
2.6K0
第85节:Java中的JavaScript
setTimeout和setInterval
setTimeout(methodName, interval); //间隔时间单位为毫秒,表示interval毫秒后执行方法methodName
tandaxia
2018/09/27
2K0
day03_js学习笔记_03_js的事件、js的BOM、js的DOM
day03_js学习笔记_03_js的事件、js的BOM、js的DOM ============================================================================= ============================================================================= 涉及到的知识点有: 五、js的事件 1、js的常用事件 onclick
黑泽君
2018/10/11
28.2K0
setTimeout定时器以及部分小知识点
思路:加一个标记flag,开始执行之后改变flag为原来的值并启动定时器,暂停的时候改变flag的值。
从入门到进错门
2018/08/21
3540
setTimeout定时器以及部分小知识点
用settimeout如何实现倒计时_javascript一分钟倒计时代码
注:setTimeout执行完可以不用执行clearTimeout,这个clearTimeout效果类似于微信撤回功能,假如setTimeout设置2分钟后自动跳转www.baidu.com,但用户在2分钟内突然不想让页面跳去baidu,执行clearTimeout就能取消这个定时操作了,但是如果2分钟都过了,显然定时器已经失效了。但是如果不执行clearInterval,setInterval就不会停止
全栈程序员站长
2022/11/09
1.4K0
js倒计时,秒倒计时,天倒计时
距某某开幕式还有 [<script language="JavaScript" type="text/javascript">djs()</script>] 天
用户3055976
2018/09/12
11.6K0
JS定时器是什么「建议收藏」
大家好,又见面了,我是你们的朋友全栈君。 很多人都会遇到图片的轮播效果,并且两分钟播放一下,这时候就会需要定时器,那么js定时器是什么?下面我们来讲解一下js定时器使用方法。 1.js定时器是什么 j
全栈程序员站长
2022/09/07
4.8K0
JS定时器是什么「建议收藏」
C1能力认证训练题解析 _ 第四部分 _ Web进阶「建议收藏」
(2)在ul中的最后一个li元素后添加一个新的li元素,li元素文字内容为input元素的输入值,请补全横线处代码(依次填写答案,使用中文逗号「,」隔开)
全栈程序员站长
2022/11/03
2.1K0
推荐阅读
相关推荐
javascript入门笔记7-计时器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档