递归题

本文通过两个典型例子:组合数计算及汉诺塔问题,详细介绍了递归算法的设计思路与实现过程。首先,利用递归原理计算从n个人中选择k人的组合数;其次,通过递归方式解决汉诺塔问题,演示如何将大盘子从A针移动到C针的过程。

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

  1. 用递归计算n个人中选择k个人组成一个委员会的不同组成。
    分析: 由n个人里面挑选k个人的组合数=有n-1个人里面选k个人+由n-1个人里选k-1个组合数。
    递归推到当n=k或者k=0时结束,因为当n=k或者k=0的时候只有一种组合数。
    代码:
# include <iostream>
using namespace std;
int comm(int n,int k){
    if(k>n)
        return 0;
    else if(n==k||k==0)
        return 1;
    else
        return comm(n-1,k)+comm(n-1,k-1);
 }
 int main(){
     int n,k;
     cout<<"输入n和k:";
     cin>>n>>k;
     cout<<"C(n,k)="<<comm(n,k)<<endl;
     return 0;
 }
  1. 汉诺塔
    有三根针A,B,C。A上面有n个盘子,盘子大小不等,大的在下,小的在上。要求把这n个盘子从A针上移到C针上,在移动过程中可以借助B针,每次只允许移动一个盘,且移动过程中在三根针上都保持大盘在下,下盘在上。
    分析:将n个盘子从A针借助C针移到B针上,然后把剩下的那个直接移到C针上,再把B针上的借助A针移到C针上。
    递归操作最后就是当n=1是,直接从A移到C。所以要n–一直减到1.
    代码:
# include <iostream>
using namespace std;
//直接把A上面的移到C上面
void move(char A,char C){
    cout<<A<<"---"<<C<<endl;
}
void move1(int n,char A,char B,char C){
    if(n=1)
        move(A,C);
    else{
        move1(n-1,A,C,B);    //把A移到B
        move(A,C);           //把剩下的直接从A移到C
        move1(n-1,B,A,C);    //把B移到C
    }
}
<think>首先,用户的问是关于递归算法的目和练习的推荐。用户说:“我想查找常见的递归算法目或练习 请问常见的递归算法目 练习 推荐”。我需要根据系统级指令来回答。 系统级指令包括: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层要求: - 回答结构清晰,帮助用户逐步解决问。 - 尽量保证回答真实可靠。 - 参考站内引用,但用户提供了引用[1]到[4],这些是关于递归的,所以我应该基于这些内容来构建回答。 引用内容: - [^1]:解释了递归的思想,用递推公式表示,如$f(n)=f(n-1)+1$,其中$f(1)=1$。 - [^2]:讨论了递归算法设计,强调数学归纳法和分治思想。 - [^3]:比较了递归和递推的区别,提到递归效率较低但结构清晰。 - [^4]:提到递归中可能重复计算,建议使用散列表优化,类似于动态规划。 我的回答需要覆盖常见的递归算法目或练习。我应该列出一些经典的递归,并确保回答结构清晰。 步骤: 1. **介绍递归算法**:简要解释递归是什么,基于引用。 2. **列出常见的递归目**:提供一些经典的递归,如斐波那契数列、阶乘、汉诺塔等。 3. **解释每个目**:对每个目简要描述问,并给出递推公式或递归关系。 4. **生成相关问**:在回答末尾添加相关问,如系统指令要求。 5. **使用LaTeX**:对于数学表达式,正确使用$...$或$$...$$格式。 常见的递归目: - 斐波那契数列:$f(n) = f(n-1) + f(n-2)$,其中$f(0)=0, f(1)=1$。 - 阶乘:$n! = n \times (n-1)!$,其中$0! = 1$。 - 汉诺塔问递归移动盘子。 - 二叉树遍历:前序、中序、后序遍历。 - 其他:如组合问、排列问、最大公约数(欧几里得算法)等。 基于引用,我可以强调递归的优化,如记忆化(来自[^4])。 回答结构: - **开头**:介绍递归算法和常见应用。 - **主体**:列出并描述几个常见目。 - **结尾**:生成相关问。 确保使用中文回答。 生成相关问: - 如系统指令示例,列出3-4个相关问,例如: 1. 如何优化递归算法? 2. 递归与迭代的区别是什么? 3. 递归在实际中的应用有哪些? 现在,构建回答。</think>### 递归算法常见目及练习推荐 递归算法是一种通过将问分解为更小的子问来求解的方法,其核心在于定义递归关系(递推公式)和边界条件。这种思想在算法设计中广泛应用,如分治法(divide and conquer),能简化复杂问的求解[^1][^2]。递归通常结构清晰,但需注意优化以避免重复计算(如使用记忆化技术)[^4]。下面我将推荐一些常见的递归算法目和练习,这些目适合初学者巩固递归思想,并逐步提升技能。每个目都附有简要描述和递归关系,帮助您理解其逻辑。 #### 1. **斐波那契数列(Fibonacci Sequence)** - **问描述**:计算第 $n$ 个斐波那契数,其中数列定义为:$f(0)=0$, $f(1)=1$, 后续每个数等于前两个数之和。 - **递归关系**:$f(n) = f(n-1) + f(n-2)$,其中 $n \geq 2$。 - **练习**:编写递归函数计算 $f(5)$,并分析时间复杂度。注意:原始递归效率较低,可结合记忆化优化(如使用散列表存储中间结果)[^4]。 - **示例代码(Python)**: ```python def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2) ``` #### 2. **阶乘计算(Factorial)** - **问描述**:计算非负整数 $n$ 的阶乘,即 $n! = n \times (n-1) \times \cdots \times 1$。 - **递归关系**:$n! = n \times (n-1)!$,其中边界条件为 $0! = 1$。 - **练习**:实现递归函数求 $5!$,并讨论递归深度限制。这是理解递归基础的好例子,强调边界条件的重要性[^1]。 - **示例代码(Python)**: ```python def factorial(n): if n == 0: return 1 return n * factorial(n-1) ``` #### 3. **汉诺塔问(Tower of Hanoi)** - **问描述**:将 $n$ 个盘子从源柱移动到目标柱,借助辅助柱,要求每次只能移动一个盘子且大盘不能压小盘。 - **递归关系**:将问分解为三步:(1) 移动 $n-1$ 个盘子到辅助柱;(2) 移动第 $n$ 个盘子到目标柱;(3) 移动 $n-1$ 个盘子到目标柱。递推公式可表示为:$T(n) = 2T(n-1) + 1$,其中 $T(1) = 1$。 - **练习**:编写递归函数解决 $n=3$ 的汉诺塔问,并输出移动步骤。此问展示递归如何简化分步操作[^2][^3]。 - **示例代码(Python)**: ```python def hanoi(n, source, auxiliary, target): if n == 1: print(f"Move disk 1 from {source} to {target}") return hanoi(n-1, source, target, auxiliary) print(f"Move disk {n} from {source} to {target}") hanoi(n-1, auxiliary, source, target) ``` #### 4. **二叉树遍历(Binary Tree Traversal)** - **问描述**:递归实现二叉树的前序、中序和后序遍历,输出节点值序列。 - **递归关系**:以中序遍历为例:遍历左子树 → 访问根节点 → 遍历右子树。递推公式为:$ \text{inorder}(root) = \text{inorder}(left) + [root] + \text{inorder}(right) $。 - **练习**:给定一个二叉树,用递归方法输出其前序序列。此问强调递归在数据结构中的应用[^2]。 - **示例代码(Python)**: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def inorder_traversal(root): if not root: return [] return inorder_traversal(root.left) + [root.val] + inorder_traversal(root.right) ``` #### 5. **最大公约数(GCD using Euclidean Algorithm)** - **问描述**:计算两个正整数 $a$ 和 $b$ 的最大公约数(GCD)。 - **递归关系**:基于欧几里得算法:$ \text{gcd}(a, b) = \text{gcd}(b, a \mod b) $,边界条件为 $b = 0$ 时返回 $a$。 - **练习**:实现递归函数求 $\text{gcd}(48, 18)$,并比较递归与迭代版本的效率。此问展示递归在数学算法中的简洁性[^3]。 - **示例代码(Python)**: ```python def gcd(a, b): if b == 0: return a return gcd(b, a % b) ``` #### 6. **组合问(Combination)** - **问描述**:计算从 $n$ 个元素中取 $k$ 个元素的组合数 $C(n, k)$。 - **递归关系**:使用二项式系数公式:$ C(n, k) = C(n-1, k-1) + C(n-1, k) $,边界条件为 $k=0$ 或 $k=n$ 时返回 1。 - **练习**:编写递归函数求 $C(5, 2)$,并讨论优化方法(如记忆化)。此问有助于理解递归在组合数学中的应用[^4]。 #### 学习建议 - **初学者路径**:从简单目如阶乘或斐波那契入手,逐步过渡到汉诺塔或二叉树遍历。 - **优化技巧**:递归可能导致栈溢出或重复计算(如斐波那契),建议使用记忆化(memoization)或转换为迭代[^4]。 - **资源推荐**:在线平台如LeetCode或GeeksforGeeks提供大量递归练习,结合引用中提到的分治思想练习[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值