循环 VS 递归:
用循环能实现的,递归都能实现 循环省空间
递归能实现的,循环不一定能 递归浪费栈空间 递归的本质,循环调用自己,我也可以说递归就是函数的循环
循环 for关键字 边界(初始条件 +结束条件) 循环体 循环变量(:每个循环的不同部分)
递归 递归方法名 边界(起始条件+结束条件) 递归体 递归变量(:每个递归的不同部分)
eg:
for i:=0;i<10;i++{//循环初始条件 循环结束条件 循环改变条件
fmt.Print(i)//循环体
}
//一个递归
func recu(i int){// i调用递归的开始条件
fmt.Print(i)//循环体
i++//循环改变条件
if i==10{//循环结束条件 也是递归条件
return
}else{
recu(i)
}
}
递归调用:递归的基本思想是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。
void recurs(argumentlist){
statements1
if(test) //test最终为false,调用链将断开
recurs(arguments)
statements2
}
如果recurs()进行了5次递归调用,则第一个statements1部分将按函数调用的顺序执行5次,然后statements2部分将以与函数调用相反的顺序执行5次。进入5层递归后,程序将沿进入的路径返回
注意,每个递归调用都创建自己的一套变量,因此当程序到达第5次调用时,将有5个独立的n变量,其中每个变量的值都不同;
上面的程序中只有一个递归,而我们在创建二叉树或其他操作时往往用到两个递归,那么我们再介绍一下包含多个递归调用的递归。调用次数将呈几何级数增长,也就是说,调用一次导致两个调用,然后导致4个调用,再导致8个调用,依次类推。这就是6层调用能够填充64个元素的原因(2^6=64).https://www.cnblogs.com/xzxl/p/7364515.html
============V=================================================================================
除了规模不同
递归必然是有去有回的,这是由递归本身的性质所决定的,至于递归算法在解决问题的时机上,有可能是在递去过程中,也有可能是在归来过程中,还有可能在两个过程中一起解决。
1.它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
2.递归需要有边界条件
递归前进段
递归返回段 当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
3.递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(Fibonacci函数)
(2)问题解法按递归算法实现。
这类问题虽则本身没有明显的递归结构,但用递归求解比迭代求解更简单,如Hanoi问题。
(3)数据的结构形式是按递归定义的。
如二叉树、广义表等,由于结构本身固有的递归特性,则它们的操作可递归地描述。
4.递归的缺点:
递归算法解题相对常用的算法如普通循环等,运行效率较低。因此,应该尽量避免使用递归,除非没有更好的算法或者某种特定情况,递归更为适合的时候。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。