算法分析与设计第二章递归与分治策略知识点与思维导图

1.递归的概念
直接或间接地调用自身的算法成为递归算法。用函数自身给出定义的函数成为递归函数。
2.递归实例
(1)阶乘函数
阶乘函数可递归的定义为 n!=1 n=0 n!=n*(n-1)! n>0
递归算法如下:
在这里插入图片描述

(2)Fibonacci数列
Fibonacci数列可递归地定义为 F(n)=1( n=0或n=1) F(n)=F(n-1)+F(n-2) n>1
递归算法如下:
在这里插入图片描述

(3)Ackerman函数:双递归函数
(4)排列问题
(5)整数划分问题
(6)汉诺塔问题
递归算法如下
在这里插入图片描述

3.分治法的基本思想
分治法的基本思想将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解决这些子问题,然后将各子问题合并得到原问题的解。

4.主定理公式
T(n)=aT(n/b)+f(n) f(n)∈θ(nd) d>=0
T(n)=θ(nd) a<bd
T(n)=θ(ndlogn) a=bd
T(n)=θ(nlogba) a>bd

5.分治实例
(1)二分搜索技术
基本思想:
将n个元素分成个数大致相同的两半,取a[n/2]与x作比较。如果x=a[n/2],则找到x,算法终止;如果x<a[n/2],则只在数组a的左半部继续搜索x;如果x>a[n/2],则只在数组a的右半部继续搜索x。

具体算法:
在这里插入图片描述

时间复杂度:
在最坏情况下,while循环被执行了O(logn)次。循环体内运算需要O(1)时间,因此整个算法在最坏情况下的计算时间复杂性为O(logn)。

(2)大整数的乘法
将n位的X,Y各自都分成2段,每段长n/2位(假设n为2的幂次).
由此,X=A2n/2+B,Y=C2n/2+D。这样,X和Y的乘积为:
XY=(A2n/2+B)(C2n/2+D)=AC*2n+(AD+BC)2n/2+BD
按此式进行计算需要进行4次n/2位整数的乘法、3次不超过2n位整数加法、以及2次移位
T(n)=O(1) n=1 T(n)=4T(n/2)+O(n) n>1 可得T(n)=O(n2).
这个式子比较麻烦,所以为了改进算法的计算复杂性,对式子进行了改进:
XY=AC
2n+((A-B)(D-C)+AC+BD)*2n/2+BD
这样看起来更复杂些,但仅需要做3次n/2位整数的乘法,6次加减法和2次移位.
T(n)=O(1) n=1 T(n)=3T(n/2)+O(n) n>1 可得T(n)=O(nlog3)=O(n1.59)

(3)Strassen矩阵乘法
使用线性代数中的思想,使用分治法,将一个矩阵转换为子矩阵相乘的方式。
T(n)=O(1) n=2 T(n)=8T(n/2)+O(n2) n>2 得出T(n)=O(n3).
但是由于此方法没有减少矩阵的乘法次数,而矩阵乘法耗费时间要比矩阵加法耗费的时间多,想要改进矩阵乘法的计算时间复杂性,必须减少乘法运算。
所以Strassen矩阵乘法用了7次对于n/2阶矩阵乘积的递归调用和18次n/2阶矩阵的加减运算。
T(n)=O(1) n=2 T(n)=7T(n/2)+O(n2) n>2 得出T(n)=O(nlog7)=O(n2.81).
由此可见,Strassen矩阵乘法的计算时间复杂性比普通矩阵乘法有较大改进。
(4)棋盘覆盖
基本思想:
用分治策略,可以设计解棋盘覆盖问题的一个简捷的算法。当k>0时,将2 k 2 k 棋盘分割为4个2 k−12 k−1 子棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为1*1棋盘。

具体算法:
实现这种分治策略的算法ChessBoard如下:
在这里插入图片描述

在这里插入图片描述

Board表示棋盘,Board[0][0]是棋盘的左上角方格。tile时全局整型变量,用来表示L型骨牌的编号,初始值为0.tr时棋盘左上角方格的行号;tc是棋盘左上角方格的列号;dr是特殊方格所在的行号;dc是特殊方格所在的列号;size是棋盘规格。

时间复杂度:
T(k)=O(1) k=0 T(k)=4T(k-1)+O(1) k>0 得出T(k)=O(4k)。
由于覆盖一个2k*2k棋盘所需的L型骨牌个数为(4k-1)/3,故算法ChessBoard是一个在渐进意义下最优的算法。

(5)合并排序
基本思想:
合并排序是用分治思想,首先将待排序元素分成大小大致相同的两个子集和,分别对两个子集和进行排序,最后将排好序的子集和合并成要求的排好序的集合。

具体算法
递归版本:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

非递归版本:
算法MergeSort的递归过程只是将待排序集合一分为二,直至待排序集合只剩下一个元素为止,然后不断合并两个排好序的数组段。按此机制,可以先将数组a中的相邻两元素两两配对,再用合并算法将它们排序,构成n/2组长度为2的排好序的子数组段,再将它们排序成长度为4的排好序的字数组段。如此下去,直至整个数组排好序。

在这里插入图片描述

在这里插入图片描述

时间复杂度:
T(n)=O(1) n<=1 T(n)=2T(n/2)+O(n) n>1
解递归方程得T(n)=O(nlogn)
空间复杂度:O(n)

(6)快速排序
基本思想:
快速排序基于分治的思想,对与输入的子数组a[p:r],按以下三个步骤进行排序。
1:分解:以a[p]为基准元素将a[p:r]划分成三段a[p:q-1],a[q]和a[q+1:r],使a[p:q-1]中任何一个元素小于等于a[q],而a[q+1:r]中任何一个元素大于等于a[q].下标q在划分过程中确定。
2:递归求解:通过递归调用快速排序算法,分别对a[p:q-1]和a[q+1:r]进行排序
3:合并:由于对a[p:q-1]和a[q+1:r]的排序是就地进行的,因此在a[p:q-1]和a[q+1:r]都已排好的序后,不需要执行任何运算,a[p:r]则已排好序。

具体算法
基准在第一个元素

在这里插入图片描述
在这里插入图片描述

随机划分基准

在这里插入图片描述

时间复杂度:
若采用第一种快排,最坏为T(n)=O(1) n<=1 T(n)=T(n-1)+O(n) n>1 求解得T(n)=n2
最好为T(n)=O(1) n<=1 T(n)=2T(n/2)+O(n) n>1 求解得T(n)=O(nlogn)
平均时间复杂度为O(nlogn)

线性时间选择求第k小
基本思想:
如果能在线性时间内找到一个划分基准,使得这个基准的划分的两个子数组的长度都至少是原来的ε倍(0 < ε< 1是某个正常数),那么在最坏情况也能O(n)时间就可以完成选择任务。可以按以下步骤找到满足要求的划分基准。
1:将n个输入元素划分成[n/5]个组,每组5个元素,除可能有一个组不是5个元素外。用任意一种排序方法,将每组中的元素排好序,并取出每组的中位数,共n/5个。
2:递归调用Select找出这n/5个元素的中位数。如果n/5是偶数,就找它的两个中位数中较大的一个。然后以这个元素作为划分基准。
3:用这个元素为基准,对原来的元素进行划分,i为分裂点
4:设k为前部分子问题元素的个数,若k<=j,则用前部分子问题递归求第k小元素;否则,则用后部分子问题递归求解第k小元素

具体算法
在这里插入图片描述

时间复杂度:
T(n)<=C1 n<75 T(n)<=C2n+T(n/5)+T((3n)/4) n>=75 求解得T(n)=O(n)

(8)最接近点对问题
基本思想:
将所给的平面上n个点的集合S分为两个子集S1和S2,每个子集中约有n/2个点,然后在每个子集中递归地求其最接近的点对。
一维:
1:将点集分成大致相等的两个部分A和B
2:递归分别求解A和B中的最近点对da,db
3:在求出一点在A中,另一点在B中的最近点对dab
4:合并得到原问题的解
d=min{da,db,dab}=min{min{da,db},dab}
二维:
1:找一条垂直线x=c(n个点x坐标的中位数),把给定的n个点分为两个包含n/2个点的子集A、B,使得A中的点位于直线的左侧或直线上,B中的点位于直线的右侧或直线上
2:在距离划分线距离为d的范围内寻找p3,q3
3:考虑A中的任意一点p,它若与B中的点q构成最接近点对的候选者,则必有distance(p,q)<d,满足这个条件的B中的点一定落在一个d*2d的矩形R中。最多存在6个点

时间复杂度
一维: T(n)=O(1) n<4 T(n)=2T(n/2)+O(n) n>=4 可解得T(n)=O(nlogn)
二维: T(n)=O(1) n<4 T(n)=2T(n/2)+O(n) n>=4 可解得T(n)=O(nlogn)

(9)循环赛日程表
基本思想:
采用分治策略,将所有的选手分成两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用对选手进行分割,直到只剩下两个选手时,比赛日程表的制定就变得很简单了。这时只需要让这两个选手进行比赛即可。

具体算法:
在这里插入图片描述

时间复杂度:O(n2)
请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值