递归就是程序自己调用自己( recursion)
一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
1.趣味问题——年龄。
有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?用递归算法实现。
可以用循环解释这道题
static int GetAge(int num) { int age = 10; while (num>1) { age += 2; num -= 1; } return age; }
换成递归
static int GetAge(int num) { if (num==1) return 10; return GetAge(num-1)+2; }
如果换成尾递归
static int GetAge(int num,int acc) { if (num == 1) return acc; return GetAge(num-1,acc+2); }
3.应用场景
删除指定路径下的文件夹里内容以及子文件夹以及子文件夹内容
static void DeleteFolder(string dir) { foreach (string d in Directory.GetFileSystemEntries(dir)) { //判断路径是否存在 if (File.Exists(d)) { FileInfo fi = new FileInfo(d); //去除文件夹的只读属性 if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) fi.Attributes = FileAttributes.Normal; File.Delete(d);//直接删除其中的文件 } else { DirectoryInfo d1 = new DirectoryInfo(d); if (d1.GetFiles().Length != 0) { DeleteFolder(d1.FullName);////递归删除子文件夹 } Directory.Delete(d); } } }
4.结
一般树状结构的都可以使用递归查询,比如 查询地区,树状的菜单等等,递归比普通的算法耗内存,谨慎使用。还有一种叫作“尾递归”就是把上一个方法的返回值当作参数传给下一个方法,不用像递归再向上返回。
汉诺塔问题
如图,汉诺塔问题是指有三根杆子A,B,C。C杆上有若干碟子,把所有碟子从A杆上移到C杆上,每次只能移动一个碟子,大的碟子不能叠在小的碟子上面。求最少要移动多少次?
当n=1时:
Move 1 from A to C
当n=2时:
Move 1 from A to B
Move 2 from A to C
Move 1 from B to C
Move 2 from A to C
Move 1 from B to C
当n=3时:
Move 1 from A to C
Move 2 from A to B
Move 1 from C to B
Move 3 from A to C
Move 1 from B to A
Move 2 from B to C
Move 1 from A to C
Move 2 from A to B
Move 1 from C to B
Move 3 from A to C
Move 1 from B to A
Move 2 from B to C
Move 1 from A to C
源代码
- static StringBuffer str = new StringBuffer();
- /**
- * //汉诺塔问题
- * @param n 盘子的个数
- * @param x 将要移动盘子柱子
- * @param y 要借用的柱子
- * @param z 要移动到的柱子
- * @return
- */
- public static String hanio(int n, Object x, Object y, Object z) {
- //String str ="";
- if(1 == n)
- str.append(move(x, n, z) + "\n");
- else {
- hanio(n-1, x, z, y);
- str.append(move(x, n, z) + "\n") ;
- hanio(n-1, y, x, z);
- }
- return str.toString();
- }
- private static String move(Object x, int n, Object y) {
- //System.out.println("Move " + n + " from " + x + " to " + y);
- return "Move " + n + " from " + x + " to " + y;
- }
fibonacci数列
斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)
源代码
- /**
- * fibonacci数列
- * @param n
- * @return
- */
- public static long fibonacci(int n) {
- if((0 == n) || (1 == n)) {
- return n;
- }else {
- return fibonacci(n-1) + fibonacci(n-2);
- }
- }
1加到n累加
用递归实现从1加到n,即1+2+3+4+...+n。
源代码
- /**
- * 累加,从1加到n,即1+2+3+4+...+n
- * @param n 要累加到的数值
- * @return 累加的结果
- */
- public static long total(int n) {
- if(1 == n) {
- return n;
- }else {
- return total(n-1) + n;
- }
- }
从1到n累积
用递归实现,从1到n累积,即1*2*3*...*n
源代码
- /**
- * 从1到n的累积,即1*2*3*...*n
- * @param n 要累乖到的数值
- * @return
- */
- public static long accumulate(int n) {
- if(1 == n) {
- return n;
- }else {
- return accumulate(n-1) * n;
- }
- }
求数组中的最大值
用递归算法求数组中的最大值。
源代码
数字塔问题
用递归算法求解数字塔问题。
n=1时
1
n=2时
1
2 2
2 2
n=3时
1
2 2
3 3 3
2 2
3 3 3
n=4时
1
2 2
3 3 3
4 4 4 4
2 2
3 3 3
4 4 4 4