收藏 分享(赏)

数据结构第6章递归.ppt

上传人:gnk289057 文档编号:12281287 上传时间:2021-12-09 格式:PPT 页数:41 大小:363KB
下载 相关 举报
数据结构第6章递归.ppt_第1页
第1页 / 共41页
数据结构第6章递归.ppt_第2页
第2页 / 共41页
数据结构第6章递归.ppt_第3页
第3页 / 共41页
数据结构第6章递归.ppt_第4页
第4页 / 共41页
数据结构第6章递归.ppt_第5页
第5页 / 共41页
点击查看更多>>
资源描述

1、第6章递归 6 3递归算法的设计 6 1什么是递归 6 2递归调用的实现原理 本章小结 6 1什么是递归6 1 1递归的定义在定义一个过程或函数时出现调用本过程或本函数的成分 称之为递归 若调用自身 称之为直接递归 若过程或函数p调用过程或函数q 而q又调用p 称之为间接递归 如果一个递归过程或递归函数中递归调用语句是最后一条执行语句 则称这种递归调用为尾递归 例6 1以下是求n n为正整数 的递归函数 intfun intn if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 在该函数fun n 求解过程中 直接调用fun n 1 语句4

2、 自身 所以它是一个直接递归函数 又由于递归调用是最后一条语句 所以它又属于尾递归 6 1 2何时使用递归在以下三种情况下 常常要用到递归的方法 1 定义是递归的有许多数学公式 数列等的定义是递归的 例如 求n 和Fibonacci数列等 这些问题的求解过程可以将其递归定义直接转化为对应的递归算法 2 数据结构是递归的有些数据结构是递归的 例如 第2章中介绍过的单链表就是一种递归数据结构 其结点类型定义如下 typedefstructLNode ElemTypedata structLNode next LinkList 该定义中 结构体LNode的定义中用到了它自身 即指针域next是一种指

3、向自身类型的指针 所以它是一种递归数据结构 对于递归数据结构 采用递归的方法编写算法既方便又有效 例如 求一个不带头结点的单链表head的所有data域 假设为int型 之和的递归算法如下 intSum LinkList head if head NULL return0 elsereturn head data Sum head next 3 问题的求解方法是递归的有些问题的解法是递归的 典型的有Hanoi问题求解 该问题描述是 设有3个分别命名为X Y和Z的塔座 在塔座X上有n个直径各不相同 从小到大依次编号为1 2 n的盘片 现要求将X塔座上的n个盘片移到塔座Z上并仍按同样顺序叠放 盘片

4、移动时必须遵守以下规则 每次只能移动一个盘片 盘片可以插在X Y和Z中任一塔座 任何时候都不能将一个较大的盘片放在较小的盘片上 设计递归求解算法 设Hanoi n x y z 表示将n个盘片从x通过y移动到z上 递归分解的过程是 Hanoi n x y z Hanoi n 1 x z y move n x z 将第n个圆盘从x移到z Hanoi n 1 y x z Hanoi问题的递归算法 voidHanoi intn charx chary charz 将n个盘片从x柱通过y柱移动到z柱 if n 1 printf t将第 d个盘片从 c柱移动到 c柱 n n x z else hanoi

5、n 1 x z y printf t将第 d个盘片从 c柱移动到 c柱 n n x z hanoi n 1 y x z 主函数 intmain intn cout n Hanoi n A B C return0 6 1 3递归模型递归模型是递归算法的抽象 它反映一个递归问题的递归结构 例如 前面的递归算法对应的递归模型如下 fun 1 1 1 fun n n fun n 1 n 1 2 其中 第一个式子给出了递归的终止条件 第二个式子给出了fun n 的值与fun n 1 的值之间的关系 我们把第一个式子称为递归出口 把第二个式子称为递归体 一般地 一个递归模型是由递归出口和递归体两部分组成

6、前者确定递归到何时结束 后者确定递归求解时的递推关系 递归出口的一般格式如下 f s1 m1 6 1 这里的s1与m1均为常量 有些递归问题可能有几个递归出口 递归体的一般格式如下 f sn 1 g f si f si 1 f sn cj cj 1 cm 6 2 其中 n i j m均为正整数 这里的sn 1是一个递归 大问题 si si 1 sn为递归 小问题 cj cj 1 cm是若干个可以直接 用非递归方法 解决的问题 g是一个非递归函数 可以直接求值 实际上 递归思路是把一个不能或不好直接求解的 大问题 转化成一个或几个 小问题 来解决 再把这些 小问题 进一步分解成更小的 小问题 来

7、解决 如此分解 直至每个 小问题 都可以直接解决 此时分解到递归出口 但递归分解不是随意的分解 递归分解要保证 大问题 与 小问题 相似 即求解过程与环境都相似 为了讨论方便 简化上述递归模型为 f s1 m1 6 3 f sn g f sn 1 c 6 4 求f sn 的分解过程如下 f sn f sn 1 f s2 f s1 一旦遇到递归出口 分解过程结束 开始求值过程 所以分解过程是 量变 过程 即原来的 大问题 在慢慢变小 但尚未解决 遇到递归出口后 便发生了 质变 即原递归问题便转化成直接问题 上面的求值过程如下 f s1 m1 f s2 g f s1 c1 f s3 g f s2

8、c2 f sn g f sn 1 cn 1 这样f sn 便计算出来了 因此 递归的执行过程由分解和求值两部分构成 6 2递归调用的实现原理用栈把本次调用的返回地址以及本次函数的参数值存储起来 每调用一次进栈一次 当返回时执行出栈处理 例 求阶乘的递归函数fun n 的执行过程 n 5时intfun intn if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 intfun intn 5 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 执行1 4句 由于第4句递归 中断地址d1 fu

9、n n 1 和参数n 5入栈 然后调用fun 4 栈 intfun intn 4 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 执行1 4句 由于第4句递归 中断地址d2 fun n 1 和参数n 4入栈 然后调用fun 3 栈 intfun intn 3 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 执行1 4句 由于第4句递归 中断地址d3 fun n 1 和参数n 3入栈 然后调用fun 2 栈 intfun intn 2 if n 1 语句1 return1 语句2

10、else 语句3 return fun n 1 n 语句4 执行1 4句 由于第4句递归 中断地址d4 fun n 1 和参数n 2入栈 然后调用fun 1 栈 intfun intn 1 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 执行1 2句 函数fun 1 1结束 返回时 从栈退出栈顶元素获得返回地址d4 并将参数n恢复为2 继续执行函数fun 2 从地址d4处继续 栈 intfun intn 2 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 执行1 2句 函数fun

11、 1 1结束 返回时 从栈退出栈顶元素获得返回地址d4 并将参数n恢复为2 继续执行函数fun 2 从地址d4处继续 其中fun n 1 1栈 intfun intn 2 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 继续执行4句 return 1 2 函数fun 2 2结束 返回时 从栈退出栈顶元素获得返回地址d3 并将参数n恢复为3 继续执行函数fun 3 从地址d3处继续 栈 intfun intn 3 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 继续执行4句 ret

12、urn 1 2 函数fun 2 2结束 返回时 从栈退出栈顶元素获得返回地址d3 并将参数n恢复为3 继续执行函数fun 3 从地址d3处继续 其中fun n 1 2栈 intfun intn 4 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 继续执行4句 return 2 3 函数fun 3 6结束 返回时 从栈退出栈顶元素获得返回地址d2 并将参数n恢复为4 继续执行函数fun 4 从地址d2处继续 栈 intfun intn 5 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语

13、句4 继续执行4句 return 2 3 函数fun 3 6结束 返回时 从栈退出栈顶元素获得返回地址d2 并将参数n恢复为4 继续执行函数fun 4 从地址d2处继续 栈 intfun intn 5 if n 1 语句1 return1 语句2 else 语句3 return fun n 1 n 语句4 继续执行4句 return 6 4 函数fun 4 24结束 返回时 从栈退出栈顶元素获得返回地址d1 并将参数n恢复为5 继续执行函数fun 5 从地址d1处继续 栈 intfun intn 5 if n 1 语句1 return1 语句2 else 语句3 return fun n 1

14、n 语句4 继续执行4句 return 24 5 函数fun 5 120结束 栈 求解fun 5 的过程如下 6 3递归算法的设计递归的求解的过程均有这样的特征 先将整个问题划分为若干个子问题 通过分别求解子问题 最后获得整个问题的解 而这些子问题具有与原问题相同的求解方法 于是可以再将它们划分成若干个子问题 分别求解 如此反复进行 直到不能再划分成子问题 或已经可以求解为止 这种自上而下将问题分解 求解 再自上而下引用 合并 求出最后解答的过程称为递归求解过程 这是一种分而治之的算法设计方法 递归算法设计先要给出递归模型 再转换成对应的C C 语言函数 递归设计的步骤如下 1 对原问题f s

15、 进行分析 假设出合理的 较小问题 f s 与数学归纳法中假设n k 1时等式成立相似 2 假设f s 是可解的 在此基础上确定f s 的解 即给出f s 与f s 之间的关系 与数学归纳法中求证n k时等式成立的过程相似 3 确定一个特定情况 如f 1 或f 0 的解 由此作为递归出口 与数学归纳法中求证n 1时等式成立相似 例如 采用递归算法求实数数组A 0 n 1 中的最小值 假设f A i 函数求数组元素A 0 A i 中的最小值 当i 0时 有f A i A 0 假设f A i 1 已求出 则f A i MIN f A i 1 A i 其中MIN 为求两个值较小值函数 因此得到如下递

16、归模型 A 0 当i 0时f A i MIN f A i 1 A i 其他情况 由此得到如下递归求解算法 floatf floatA inti floatm if i 0 returnA 0 else m f A i 1 if m A i returnA i elsereturnm 例6 2 利用串的基本运算写出对串求逆的递归算法 解 设f s s的逆串 Stringinvert string 例6 3求顺序表L的最大元素 ElemTypeMax SqListL inti intj 求第i j元素中的最大值 intmid ElemTypemax max1 max2 if i j max L d

17、ata i else mid i j 2 max1 Max L i mid 求第i mid元素中的最大值max2 Max L mid 1 j 求第mid j元素中的最大值max max1 max2 max1 max2 returnmax 例6 5n皇后问题 在n n的方格棋盘上 放置n个皇后 要求每个皇后在不同行 不同列 不同左右对角线 intq 9 0 1 5 8 6 3 7 2 4 q 列 行 设place k n 是在第1 k 1列已经放好皇后 现要在第k n列上放皇后 constintN 20 intq N 1 q j i 第j列的皇后在第i行voidplace intk intn 第1 k 1列皇后已经放好 现放第k列的皇后 if k n print n 当k n时 输出解elsefor inti 1 i n i if find i k 若 i k 位置可放皇后 q k i 记录第k列的皇后位置iplace k 1 n 继续第k 1 n列 intfind inti intk 第1 k 1列皇后已经放好 测试第k列的 第i行上能否放置皇后 intj 1 while j n place 1 n return0 练习教材中p145的习题1和2 1 2 3 4

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报