递归算法的学习

能采用递归描述的算法通常有这样的特征:为求解规模为N的问题,设法将它分解成规模较小的问题, 然后从这些小问题的解方便地构造出大问题的解,并且这些规模较小的问题也能采用同样的分解和综合方法, 分解成规模更小的问题,并从这些更小问题的解构造出规模较大问题的解。特别地,当规模N=1时,能直接得解。

示例:小猴吃枣

小猴第一天摘下若干枣子,当即吃掉了一半,不过瘾又多吃了一个;第二天吃了剩下的一半又多吃了一个;
以后每一天都吃了前一天剩下的一半多一个。到第十天小猴再想吃时,见到只剩下一只枣子了。问第一天这堆枣子有多少?

从上题中我们可看到一个令人欣喜的规律,第十天为1,第九到第一天中后一天与1的和的两倍与前一天相等。
下面就对这一规律做了描述:(完整的程序请下载)

public int taozi(int x){
  if(x>=10) {
   return 1;
  }
  else{
    return 2*(taozi(x+1)+1);
  }
}

我们定义taozi()函数的时候通过taozi()自身来进行了定义,这就是递归。 递归是个特殊的循环,是一个有着非常美妙的循环规则的循环。 上题中我们只要将taozi(1),即第一天打印出来,一切OK。而这中间究竟是怎么工作的,我们可以不管。

【问题】 组合问题
问题描述:找出从自然数1、2、……、n中任取r个数的所有组合。
例如 n=5,r=3的所有组合为: 
(1)5、4、3   (2)5、4、2    (3)5、4、1
(4)5、3、2    (5)5、3、1    (6)5、2、1
(7)4、3、2    (8)4、3、1    (9)4、2、1
(10)3、2、1

分析所列的10个组合,可以采用这样的递归思想来考虑求组合函数的算法。 设函数为public void comb(int m,int k)为找出从自然数1、2、……、m中任取k个数的所有组合。 当组合的第一个数字选定时,其后的数字是从余下的m-1个数中取k-1数的组合。
这就将求m 个数中取k个数的组合问题转化成求m-1个数中取k-1个数的组合问题。

设函数引入工作数组a[]存放求出的组合的数字,约定函数将确定的k个数字组合的第一个数字放在a[k]中, 当一个组合求出后,才将a[]中的一个组合输出。

第一个数可以是m、m-1、……、k,函数将确定组合的第一个数字放入数组后, 有两种可能的选择,因还未确定组合的其余元素,继续递归去确定;或因已确定了组合的全部元素, 输出这个组合。细节见以下程序:

public class CombTest{
 static int   a[]=new int[100];
 static void  comb(int m,int k) {
   int i,j;
   for (i=m;i>=k;i--)  {
     a[k]=i;
      if (k>1)
         comb(i-1,k-1);
      else {
           for (j=a[0];j>0;j--)
            System.out.printf("%4d",a[j]);
            System.out.println();
      }
   }
}
 public static void main(String args[]) {
      a[0]=3;
      comb(5,3);
     // a[0]=4;
     // comb(10,4);
 }
}
运行:C:\java>java    CombTest   5   4   3   5   4   2   5   4   1   5   3   2   5   3   1   5   2   1   4   3   2   4   3   1   4   2   1   3   2   1
时间: 2024-10-11 20:51:54

递归算法的学习的相关文章

算法学习(二) 全排列问题的非递归算法——模拟堆栈

前一段时间总结了全排列问题的几种递归解法,今天再总结一下如何通过对系统栈行为的模拟来非递归的实现全排列问题. 我们用一个数组stack[]来表示一个栈,用一个top指针来表示栈顶,用一个flags[]数组来标示每一个数字的可用性:用i来表示当前的状态. 初始状态top=0:i=-1:flags数组全为1: i递增,如果i没有越界并且flags[i]==1,那么就将i写入栈中,栈顶往前移动一位:最后把flags[i]赋值为0,i回溯到初始状态-1: 当栈顶越界,就将整个栈的信息打印出来,然后top

算法学习(4)----汉诺塔递归算法和非递归算法

学习<算法设计与分析基础>,习题2.4 第5题要求为汉诺塔游戏设计一个非递归的算法. 思,不得其解.看书后答案提示: 你如果做不到,也不要沮丧:这个问题的非递归算法虽然不复杂,但却不容易发现.作为一种安慰,可以在因特网上寻找答案. 好吧,话都说得这么直接了,遂百度之,得到一个感觉很好的答案,略做修改,摘录于下: 原文地址:http://blog.sina.com.cn/s/blog_48e3f9cd01000474.html ##################################

java基础学习总结五(递归算法、冒泡排序)

一:递归算法 概念:自己调用自己的方法 示例代码如下: 1 @Test 2 /** 3 * 递归求和 4 * 5+4+3+2+1=15 5 */ 6 public void getSum() { 7 long sum = sum(5); 8 System.out.println("sum=" + sum); 9 } 10 11 public static long sum(int i) { 12 if (1 == i) { 13 return 1; 14 } else { 15 ret

python的递归算法学习(3):汉诺塔递归算法

汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶.所有碟子按从大到小的次序从塔底堆放至塔顶.紧挨着这座塔有另外两个钻石宝塔B和C.从世界创始之日起,波罗门的牧师就一直在试图把塔A上的碟子移动到C上去,其间借助于塔B的帮助.每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面.当牧师们完成这个任务时,世界末日也就到了. 对于汉诺塔问题的求解,可以通过以下3步实现: (1)将塔A上的n -1个碟子借助C塔先移动到B塔上: (2)

我的Java开发学习之旅------&gt;使用循环递归算法把数组里数据数组合全部列出

面试题如下:把一个数组里的数组合全部列出,比如1和2列出来为1,2,12,21. (面试题出自<Java程序员面试宝典>) 代码如下: import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * 把一个数组里的数组集合全部列出,比如1和2列出来为1,2,12,21 */ public class ListAll { public static void main(String[] args

python的递归算法学习(2):具体实现:斐波那契和其中的陷阱

1.斐波那契 什么是斐波那契,斐波那契额就是一个序列的整数的排序,其定义如下: Fn = Fn-1 + Fn-2 with F0 = 0 and F1 = 1 也就是,0,1,1,2,3,5,8,13..... 递归实现: def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2) 非递归实现: def fibi(n): a, b = 0, 1 for i in range(n):

算法第四版学习笔记二(有趣的递归算法)

1.public static String exR1(int n){ if(n<=0) return ""; return exR1(n-3)+ n + exR1(n-2) + n; } System.out.println(exR1(6)); //311361142246 2.public static String exR2(int n){ String s = exR1(n-3)+ n + exR1(n-2) + n; if(n<=0) return "&

IOS 阶段学习第八天笔记(指针)

                                                        IOS学习(C语言)知识点整理 一.指针 1)概念:存储变量的地址的一个变量. 2) 数据存储类型分析 1.text (代码段) :存储二进制的可执行代码 2.data(初始化的数据段) 存储初始化的全局变量以及初始化的static修饰的变量,分为只读数据段 (如:字符串常量,整型常量)及可读可写数据段,静态存储. 3.data(未初始化的数据段)存储未初始化的全局变量及未初始化的st

nodejs学习资料

NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. 每一种解析器都是一个运行环境,不但允许JS定义各种数据结构,进行各种计算,还允许JS使用运行环境提供的内置对象和方法做一些事情.例如运行在浏览器中的JS的用途是操作DOM,浏览器就提供了document之类的内置对象.而运行在NodeJS中的JS的用途是操作磁盘文件或搭建HTTP服务器,NodeJS