【算法】递归与while循环的通俗比较

本文对比了递归与循环在代码实现上的区别,并探讨了它们的概念、优缺点及适用范围。通过具体实例说明了递归如何将复杂问题转化为简单问题,而循环则是在满足条件时重复执行同一段代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引入

说起循环,我们大多会想到“递归、迭代、遍历”等几个词,具体的含义请看本文附录。今天只结合具体例子说一说递归和while循环的比较。

两者的代码比较

问:求1+2+3+…+n的和,请用两种方法写出代码?

答:

递归代码:

 public static int Fun(int n){  
        if(n == 1){  
            return 1;  
        }  
        else {  
            return n + Fun(n-1);  
        }  
    } 

while循环代码:

public class me{
            public static void main(String[] args){
            int sum=0;
            int i=1;
            while(i<=n){
            sum+=i;
            i++;
                }
            System.Out.println("sum="+sum);  

两者的概念比较

递归(recursion):在函数内调用自身,将复杂情况逐步转化成基本情况。有网友说:递归就是包子馅包子,它的极限就是馒头。仔细想想,哈哈,就是这么个理儿。递归分为线性递归和尾递归。

举个栗子,已知f(2)=3,f(n)=f(n-1)+n,求f(5)?

答:f(5)=f(4)+5=f(3)+4+5=f(2)+3+4+5=15

怎么样,当发现自己在高中时就利用过递归思想,有没有一种原来自己从小就这么厉害了的自豪感。偷笑

这里的f(2)就是基线条件,这似乎就是人们所说的“出口”。基线条件就是函数没必要再循环下去了。


循环(loop):在满足条件的情况下,重复执行同一段代码,比如while语句。

这个简单,不再赘述。

综上。看到一个网友这样描述两者:递归就像小明要去楼顶取东西,从一楼开始爬,看,不是的,继续爬,每层楼梯看上去都一样,但1到2,2到3的楼梯是两个楼梯,等到了楼顶,取到东西,不能直接跳楼跳下来,还得从楼顶一层层退回来。

而while循环,就像驴子拉磨,无论跑多少次,都是在原地。变化的只是磨盘里的磨的东西,而不是驴每圈所在的不同位置。

优缺点比较

递归

优点:代码更简洁清晰,可读性更好。

缺点:由于递归需要系统堆栈,所以空间消耗要比非递归代码要大很多。而且,如果递归深度太大,可能系统撑不住。

循环

优点:速度快,结构简单

缺点:并不能解决所有的问题

使用范围比较

循环能干的事,递归都能干;递归能干的事,循环不一定能干。如果使用循环并不困难的话,最好使用循环。

附录

循环和递归在上面已说,在此不再赘述。下面说说迭代和遍历。

迭代(iterate):在数学中:在多次循环中逐步接近结果。

           在编程中:按顺序访问一个列表中的每一项。适用于线性结构,如数组和队列

遍历(traversal):按规则访问结构中的每一项,且每项只访问一次。适用于非线性结构,如树,图。

小结

(1)至于两者的转换,又是另一个问题了。

(2)对递归的真正理解,还需在真正使用中体会。

(3)感谢广大网友给的参考。


### 回溯算法的原理 回溯算法是一种系统性地探索问题解空间的算法思想,通常用于解决组合、排列、搜索等需要尝试所有可能情况的问题。其核心思想是:**通过递归的方式尝试所有可能的选择,在遇到不符合条件的情况时“回退”到上一步,重新选择路径**。 在实现过程中,回溯算法会构建一棵解空间树(通常是隐式的),每一条从根节点到叶节点的路径代表一个候选解。当发现当前路径无法满足约束条件时,算法会“剪枝”,即放弃该路径,并回退至上一层继续尝试其他分支[^1]。 ### 回溯算法的基本结构 回溯算法通常采用递归方式实现,其基本结构如下: ```python def backtrack(path, choices): if 满足结束条件: 将path加入结果集 return for 选择 in 可选的choices: 做出选择(将当前选项加入path) 调用backtrack函数进入下一层 撤销选择(回溯到上一层的状态) ``` 这种结构体现了“试探-失败-回退”的过程。其中,“撤销选择”是回溯算法的关键,它确保了每次递归调用返回后能恢复到之前的状态,从而尝试新的路径。 ### 应用场景示例 #### 1. 全排列问题 全排列问题是经典的回溯应用,要求生成给定元素的所有可能排列。例如,输入 `[1,2,3]`,应输出所有可能的排列组合。 ```python def permute(nums): res = [] def backtrack(path, remaining): if not remaining: res.append(path[:]) return for i in range(len(remaining)): # 做出选择 path.append(remaining[i]) # 进入下一层决策 backtrack(path, remaining[:i] + remaining[i+1:]) # 回溯,撤销选择 path.pop() backtrack([], nums) return res # 示例使用 print(permute([1, 2, 3])) ``` #### 2. 组合总问题 组合总问题要求找出所有满足目标值的组合,例如从数组中选出若干数,使其等于指定目标值。 ```python def combination_sum(candidates, target): res = [] def backtrack(start, path, total): if total == target: res.append(path[:]) return if total > target: return for i in range(start, len(candidates)): # 做出选择 path.append(candidates[i]) # 继续在同一层或下一层尝试 backtrack(i, path, total + candidates[i]) # 回溯 path.pop() backtrack(0, [], 0) return res # 示例使用 print(combination_sum([2, 3, 6, 7], 7)) ``` #### 3. N皇后问题 N皇后问题是一个典型的约束满足问题,要求在一个 N×N 的棋盘上放置 N 个皇后,使得它们彼此不能攻击。该问题广泛使用回溯算法进行求解。 ```python def solve_n_queens(n): res = [] def is_valid(board, row, col): # 判断是否可以在 board[row][col] 放置皇后 for i in range(row): if board[i][col] == 'Q': return False # 检查左上方是否有皇后 i, j = row - 1, col - 1 while i >= 0 and j >= 0: if board[i][j] == 'Q': return False i -= 1 j -= 1 # 检查右上方是否有皇后 i, j = row - 1, col + 1 while i >= 0 and j < n: if board[i][j] == 'Q': return False i -= 1 j += 1 return True def backtrack(row, board): if row == n: res.append([''.join(r) for r in board]) return for col in range(n): if is_valid(board, row, col): board[row][col] = 'Q' backtrack(row + 1, board) board[row][col] = '.' # 回溯 backtrack(0, [['.'] * n for _ in range(n)]) return res # 示例使用 for solution in solve_n_queens(4): for row in solution: print(row) print() ``` ### 回溯算法的优化策略 尽管回溯算法可以系统性地遍历解空间,但其时间复杂度往往较高,因此常结合以下策略进行优化: - **剪枝**:提前判断某些路径不可能满足条件,避免无效递归。 - **记忆化搜索**:对重复子问题进行缓存,避免重复计算。 - **启发式搜索**:引入启发函数优先探索更有可能成功的路径。 这些优化手段在实际编程中可以显著提升算法效率,尤其是在大规模数据处理场景中更为重要[^1]。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡夫卡的熊kfk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值