谈谈递归与循环
很久没有写技术文章了,重新提笔希望这次能坚持下去。端午小长假随手给游戏的公会写了一个抽奖程序,在写抽奖核心逻辑的过程中,遇到了for循环无法解决的坑,尝试了很多种方法都没达到理想的效果,睡了一晚,早上醒来突然想到递归函数,于是尝试将原先的循环改成递归之后达到了想要的效果,遂想好好整理一下循环和递归的区别以及使用场景,供自己日后查阅。
先拿最简单的从1到n的求和举例,先来看循环的写法:
function sumFunc(n){
let count = 0;
if(n<0){
return -1;
}
for(let i = 0; i <= n; i++){
count += i;
}
return count;
}
再来看看递归的写法:
function sumRecursive(n){
if(n == 0){
return 0;
}else{
return sumRecursive(n-1) + n;
}
}
由上述对比可以看出,递归和循环本质都是复用代码块。递归看起来更简洁、易读一些。
接着我们来测试下运行时间,假定上述函数都运行10000次:
console.time("test4sumFunc")
sumFunc(10000)
console.timeEnd("test4sumFunc")
test4sumFunc: 0.183837890625ms
console.time("test4sumRecursive")
sumFunc(10000)
console.timeEnd("test4sumRecursive")
test4sumRecursive: 0.173095703125ms
以上是分别贴代码的运行效率,虽然从上面的数据来看两者运行效率差不多,甚至递归更快。但经多次测试发现,结果都不太一致。更多的时候,循环的执行效率比递归更高。
经查阅资料后得知,递归函数的循环体是函数,执行函数会占用系统栈,而循环不需要占用系统栈。因此,循环在很多应用级的编程语言中更具优势。但其实在实际应用之中,更多情况是各有千秋。
回想之前遇到的场景,现在总结如下情况使用递归更合适:
- 倒计时应用.
- 轮播图.
- 在需要频繁进行数据操作的时候,递归可以规避一些循环难以解决的问题(如我抽奖小程序中,每次抽取一个中奖者之后需要将其从奖池中移除)
暂时就想到这些,以后再遇到其他的应用场景再回来做补充。
参考文章: