C++常用算法之递归
2011-08-25 09:46
197 查看
在数学中经常用一个函数本身来定义该函数。例如阶乘函数f (n) =n!的定义如下:
![](http://hi.csdn.net/attachment/201108/1/0_13121797925SSV.gif)
其中n 为整数。
从该定义中可以看到,当n 小于或等于1时,f (n)的值为1,如f (-3) = f (0) = f (1) =1。当n大于1时,f (n)由递归形式来定义,在定义的右侧也出现了f 。在右侧使用f 并不会导致循环定义,因为右侧f 的参数小于左侧f 的参数。例如,从公式(1 - 1)中可以得到f ( 2 ) = 2f ( 1 ),由于我们已经知道f ( 1 ) = 1,因此f ( 2 ) = 2 * 1 = 2。以此类推,f ( 3 ) = 3f ( 2 ) = 3 * 2 = 6。对于函数f (n) 的一个递归定义(假定是直接递归),要想使它成为一个完整的定义,必须
满足如下条件:
• 定义中必须包含一个基本部分( b a s e),其中对于n 的一个或多个值,f (n)必须是直接定义的(即非递归)。为简单起见,我们假定基本部分包含了n≤k 的情况,其中k 为常数。(在基本部分中指定n≥k 的情形也是可能的,但较少见。)
• 在递归部分(recursive component)中,右侧所出现的所有f 的参数都必须有一个比n 小,以便重复运用递归部分来改变右侧出现的f ,直至出现f 的基本部分。在公式(1 - 1)中,基本部分是:当n≤1时f (n) = 1;递归部分是f (n) = nf (n- 1 ),其中右侧f的参数为n- 1,比n 要小。重复应用递归部分可把f (n- 1 )变换成对f (n- 2 ),f (n- 3 ),⋯,直到f ( 1 )的调用。下面我们来看一个例子:
-->编写一个递归函数,用来输出n 个元素的所有子集。
a,b 和c 的排列方式有:a b c, a c b, b a c, b c a, cab 和c b a。n 个元素的排列方式共有n !种。由于采用非递归的C + +函数来输出n 个元素的所有排列方式很困难,所以可以开发一个递归函数来实现。令E= {e1 , ..., en }表示n 个元素的集合,我们的目标是生成该集合的所有排列方式。令Ei 为E中移去元素i 以后所获得的集合,perm (X) 表示集合X 中元素的排列方式,ei . p e r m(X)表示在perm (X) 中的每个排列方式的前面均加上ei
以后所得到的排列方式。例如,如果E= {a, b, c},那么E1= {b, c},perm (E1 ) = ( b c, c b),e1 .perm (E1) = (a b c, a c b)。对于递归的基本部分,采用n = 1。当只有一个元素时,只可能产生一种排列方式,所以perm (E) = ( e),其中e 是E 中的唯一元素。当n > 1时,perm (E) = e1 .perm (E1 ) +e2 .p e r m(E2 ) +e3.perm (E3) + ⋯ +en .perm (En )。这种递归定义形式是采用n
个perm (X) 来定义perm (E), 其中每个X 包含n- 1个元素。至此,一个完整的递归定义所需要的基本部分和递归部分都已完成。
![](http://hi.csdn.net/attachment/201108/1/0_13121797925SSV.gif)
其中n 为整数。
从该定义中可以看到,当n 小于或等于1时,f (n)的值为1,如f (-3) = f (0) = f (1) =1。当n大于1时,f (n)由递归形式来定义,在定义的右侧也出现了f 。在右侧使用f 并不会导致循环定义,因为右侧f 的参数小于左侧f 的参数。例如,从公式(1 - 1)中可以得到f ( 2 ) = 2f ( 1 ),由于我们已经知道f ( 1 ) = 1,因此f ( 2 ) = 2 * 1 = 2。以此类推,f ( 3 ) = 3f ( 2 ) = 3 * 2 = 6。对于函数f (n) 的一个递归定义(假定是直接递归),要想使它成为一个完整的定义,必须
满足如下条件:
• 定义中必须包含一个基本部分( b a s e),其中对于n 的一个或多个值,f (n)必须是直接定义的(即非递归)。为简单起见,我们假定基本部分包含了n≤k 的情况,其中k 为常数。(在基本部分中指定n≥k 的情形也是可能的,但较少见。)
• 在递归部分(recursive component)中,右侧所出现的所有f 的参数都必须有一个比n 小,以便重复运用递归部分来改变右侧出现的f ,直至出现f 的基本部分。在公式(1 - 1)中,基本部分是:当n≤1时f (n) = 1;递归部分是f (n) = nf (n- 1 ),其中右侧f的参数为n- 1,比n 要小。重复应用递归部分可把f (n- 1 )变换成对f (n- 2 ),f (n- 3 ),⋯,直到f ( 1 )的调用。下面我们来看一个例子:
-->编写一个递归函数,用来输出n 个元素的所有子集。
a,b 和c 的排列方式有:a b c, a c b, b a c, b c a, cab 和c b a。n 个元素的排列方式共有n !种。由于采用非递归的C + +函数来输出n 个元素的所有排列方式很困难,所以可以开发一个递归函数来实现。令E= {e1 , ..., en }表示n 个元素的集合,我们的目标是生成该集合的所有排列方式。令Ei 为E中移去元素i 以后所获得的集合,perm (X) 表示集合X 中元素的排列方式,ei . p e r m(X)表示在perm (X) 中的每个排列方式的前面均加上ei
以后所得到的排列方式。例如,如果E= {a, b, c},那么E1= {b, c},perm (E1 ) = ( b c, c b),e1 .perm (E1) = (a b c, a c b)。对于递归的基本部分,采用n = 1。当只有一个元素时,只可能产生一种排列方式,所以perm (E) = ( e),其中e 是E 中的唯一元素。当n > 1时,perm (E) = e1 .perm (E1 ) +e2 .p e r m(E2 ) +e3.perm (E3) + ⋯ +en .perm (En )。这种递归定义形式是采用n
个perm (X) 来定义perm (E), 其中每个X 包含n- 1个元素。至此,一个完整的递归定义所需要的基本部分和递归部分都已完成。
相关文章推荐
- C++常用算法总结 doc
- 20170219C++项目班02_02递归下降算法/解析器/Scanner实现
- C/C++常用算法【C语言顺序查找(随机数)】【1】
- 三种常用算法概述——遍试、迭代、递归
- 【C++研发面试笔记】20. 常用算法-路径搜索算法(图算法)
- 常用算法经典代码(C++版)
- C++ 常用泛型算法的使用
- 常用算法的递归实现问题分析(针对《数据结构与程序设计》by Robert.L.Kruse)
- C++常用的递归代码
- 每日一个算法------二叉树实现、递归和非递归算法(c++版)
- C++ 递归位置排列算法及其应用
- C++和Matlab最常用的编程技能,实现复杂算法的基础
- 【C++研发面试笔记】21. 常用算法-STL中常用算法函数
- 蓝桥杯常用算法知识点:【递归】求n个元素的全排列
- 常用算法经典代码(C++版)
- Java常用算法——迭代 & 递归篇
- Javascript迭代、迭代、穷举、递归常用算法
- 蓝桥杯常用算法知识点:1.递归与循环
- c++基础8:常用的数据结构及算法
- C++ 常用算法的应用实例