C语言函数递归经典例题:汉诺塔和小青蛙跳台阶

news2024/10/17 10:50:42

目录

  • 汉诺塔
    • 问题描述
    • 思路
    • 代码实现
    • 思考:怎么判断一共要移动几次?(时间复杂度?)
  • 小青蛙跳台阶
    • BC117 小乐乐走台阶
    • 问题描述
    • 递归
    • 动态规划
    • 迭代

汉诺塔

问题描述

将塔A的柱子移动到塔C
要求:

  1. 大的柱子只能在小的柱子下面
  2. 一次只能移动一个柱子
    在这里插入图片描述

思路

想把A上的n个柱子移动到C 核心思路是:
S1:先把A上面n-1个柱子移动到B
S2:再把A剩下的1个柱子移动到C
S3:最后把B上的n-1个柱子移动到C

  1. 本题显然可以分裂出子问题 移动n个柱子从A到C移动n-1个柱子从B到C是类似的问题
    在这里插入图片描述
  2. 假设 void Hanoi(int n, char source, char auxiliary, char target)的功能是:
    把在source(源头塔)上的n个柱子 利用auxiliary(辅助塔) 移动到target(目标塔)
  3. 看下面代码的时候 不要受参数名影响(B有时候作为目标塔 有时候作为辅助塔 这取决于传参的顺序)
    就这么理解:Hanoi()的功能是把第二个参数上的n个柱子 利用第三个参数 移动到第四个参数上去
  4. 递归的出口:只有一个柱子的时候 结束递 开始"归" 一个柱子直接移动就行了
  5. 每次调用都是一层一层往上 越来越接近1个柱子的情况
  6. move函数只是模拟了移动这个行为 move(‘A’,‘C’)就表示把A塔上第一个柱子移动到C塔上去

代码实现

假设出函数的功能 同时有了子问题如何分裂的思路之后
直接顺着这个思路写下去 那就对了!!

void move(char ch1, char ch2)
{
	printf("%c----->%c\n", ch1, ch2);
}

void Hanoi(int n, char source, char auxiliary, char target)
{
	//如果只有1个柱子 直接移动到目标塔就行
	if (n == 1)
	{
		move(source, target);
	}
	//不止1个柱子 接收到的参数是A B C
	else//n>=2
	{
		//S1:先把A上面n-1个柱子移动到B
		Hanoi(n - 1, source, target, auxiliary);
		//S2:再把A剩下的1个柱子移动到C
		move(source, target);
		//S3:最后把B上的n-1个柱子移动到C
		Hanoi(n - 1, auxiliary, source, target);
	}
}

int main()
{
	Hanoi(3, 'A', 'B', 'C');
	return 0;
}

思考:怎么判断一共要移动几次?(时间复杂度?)

  • 根据子问题的递推规则发现:
    n个柱子移动次数是1+2*(n-1个柱子的移动次数)
  • 进一步找规律发现:
    n个柱子需要移动2^n-1
  • 也就是说时间复杂度是O(2^n) 其中n是盘子的数量
  • 这个复杂度已经相当高了 在2.00GHz的处理器下 64个柱子要跑270多年
    在这里插入图片描述

小青蛙跳台阶

BC117 小乐乐走台阶

在牛客网上有一道类似的题目 可以先尝试做一做
题目链接

问题描述

一只青蛙
他可以一次跳一级台阶
或者一次跳两级台阶
假设青蛙要跳上n级台阶
请问一共有多少种跳法?
在这里插入图片描述

递归

  • 这道题和斐波那契数列十分类似 只不过斐波那契数列我们直接知道 第三个数开始 每个数就是前两个数之和
  • 而这道题 青蛙跳上一级台阶 只有1种跳法 ;跳上二级台阶 有2种跳法
  • 思考:跳上第n级(n>=3)呢?
  • 假设我给定一个函数 frogJumps(int steps) 假设它的功能就是:可以计算出青蛙跳到steps级台阶有多少种跳法
  • 假设青蛙第一次跳了1级 那么剩下的跳法就是frogJumps(n-1)
  • 假设青蛙第一次跳了2级 那么剩下的跳法就是frogJumps(n-2)
  • 所以所有的跳法就是frogJumps(n-1) + frogJumps(n-2) 当n>=3
  • 只要有了递推公式 递归的代码其实很容易写出来
int frogJumps(int steps)
{
	if (steps <= 2)
		return steps;
	else
		return frogJumps(steps - 1) + frogJumps(steps - 2);
}

int main()
{
	printf("%d ", frogJumps(1));
	printf("%d ", frogJumps(2));
	printf("%d ", frogJumps(3));
	printf("%d ", frogJumps(4));
	printf("%d ", frogJumps(5));
	return 0;
}

动态规划

不管是用递归计算n! 还是递归求第n个斐波那契数量
递归代码虽十分简洁 但是有一个很严重的问题:递归很容易产生大量的重复计算
但是实际上:

  • 在计算10!的时候 就已经产生9! 8! 7!..了
  • 在计算第40个斐波那契数的时候 前面的斐波那契数其实也都已经计算过了
  • 那么 该怎么把这些已经计算过的子问题 给利用起来 帮助计算下一个子问题呢?

这就引出了动态规划的一个典型的思想:利用上一步的计算结果 快速计算出下一步的结果
下面可以看看动态规划会怎么计算这道题:

  • 台阶的级数n和几种跳法 其实是一 一对应的 --> 数组
    在这里插入图片描述
#define N 10
int main()
{
	int arr[N] = { 0 };
	arr[0] = 1;
	arr[1] = 2;
	//前两个子问题的解直接给出
	//从第三个子问题开始(i=2) 计算得出
	for (int i = 2; i < N; i++)
		arr[i] = arr[i - 1] + arr[i - 2];

	//当循环结束 其实数组里已经放好了1~N级台阶对应的跳法
	for (int i = 0; i < N; i++)
		printf("青蛙跳上%d级台阶有%d种跳法\n", i + 1, arr[i]);
	return 0;
}

迭代

● 尝试用while改写(和斐波那契一样的) 因为n很大的时候 递归效率太差
● 求n个台阶有几种跳法 其实就相当于求第n个"斐波那契数"
● 核心在于while的循环条件是什么

int Fib(int index)
{
	//如果index 1 2 直接返回即可
	if (index <= 2)
		return index;

	//如果能走到这里 就说明index>=3了 那就计算求出第index个数(也就是index级台阶有几种跳法)
	int a = 1;
	int b = 2;
	int tmp = 0;
	while (index >= 3)//3级 循环1次 把tmp返回;4级 循环2次 把tmp返回....
	{
		tmp = a + b;
		a = b;
		b = tmp;
		index--;
	}
	return tmp;
}

int main()
{
	printf("%d\n", Fib(1));
	printf("%d\n", Fib(2));
	printf("%d\n", Fib(3));
	printf("%d\n", Fib(4));
	printf("%d\n", Fib(5));
	printf("%d\n", Fib(6));
	printf("%d\n", Fib(7));
	printf("%d\n", Fib(8));
	printf("%d\n", Fib(9));
	printf("%d\n", Fib(10));
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2216999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习100天第11天之文件和异常

1 前言 实际开发中常常会遇到对数据进行持久化操作的场景&#xff0c;而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词&#xff0c;可能需要先科普一下关于文件系统的知识&#xff0c;但是这里我们并不浪费笔墨介绍这个概念&#xff0c;请大家自…

请求第三方接口有反斜杠和双引号怎么处理,且做格式校验?

如&#xff1a;接口文档要求 直接使用转义失败&#xff0c;在postman中填值请求正常。 String para "[" "\\" "\"" "预计今天白天我市多云间晴&#xff1b;" "\\" "\"]"; System.err.println(pa…

QT的文件操作类 QFile

QFile 是 Qt 框架中用于文件处理的一个类。它提供了读取和写入文件的功能&#xff0c;支持文本和二进制文 件。 QFile 继承自 QIODevice &#xff0c;因此它可以像其他IO设备一样使用。 主要功能 文件读写&#xff1a; QFile 支持打开文件进行读取或写入操作文件信息&#x…

LinkedList和链表(上)

1. 顺序表ArrayList的缺点和优点 优点: 1> 在给定下标进行查找的时候,时间复杂度是O(1) 缺点: 1> 插入数据必须移动其他数据,最坏情况下,插入到0位置,时间复杂度为O(N) 2> 删除数据也需要移动数据,最坏情况下,就是删除0位置.时间复杂度为O(N) 3> 扩容之后(1.5倍扩容…

[PHP]Undefined index错误只针对数组

1、示例一 <?php $a null; var_dump($a[name]); 结果&#xff1a;无报错 2、示例二 <?php $a []; var_dump($a[name]);结果&#xff1a;报错

v853 tina 文件系统挂载不全问题

文章目录 1、前言2、环境介绍3、解决 1、前言 正常文件系统挂载后应如下图所示&#xff1a; 但目前是这样&#xff1a; 2、环境介绍 硬件&#xff1a;韦东山v853 aicit板卡 软件&#xff1a;v853 tina sdk 3、解决 menuconfig中开启e2fsprogs&#xff1a; Utilities ---&…

C++ —— 关于继承(inheritance)

目录 1. 继承的概念及定义 1.1 继承的概念 1.2 继承的定义格式 1.3 继承基类成员访问方式的变化 1.4 类模板的继承 2.基类与派生类的转换 3. 继承中的作用域 3.1 隐藏规则 4. 派⽣类的默认成员函数 4.1 4个常见默认成员函数 4.2 实现⼀个不能被继承的类 5. 继承与友元…

房产销售系统(论文+源码)_kaic

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于房产销售系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了房产销售系统&#xff0c;它彻底改变了过去传统的…

wps安装教程

WPS office完整版是一款由金山推出的免费办公软件&#xff0c;软件小巧安装快&#xff0c;占用内存极小&#xff0c;启动速度快。WPS office完整版包含WPS文字、WPS表格、WPS演示三大功能模块&#xff0c;让我们轻松办公。WPS的功能是依据OFFICE用户的使用习惯而设计&#xff0…

ios局域网访问主机Xcode配置

前景&#xff1a; 公司业务是做智能家居&#xff0c;所有设备通过主机控制&#xff0c;目前有个产品需求是&#xff0c;在没有外网的情况下依然能够通过局域网控制主机的设备。 IOS开发需要做的&#xff1a; 除了业务代码之外&#xff0c;前提还要配置访问局域网功能。有以下…

专升本:开启人生新征程

在当今社会&#xff0c;学历的重要性日益凸显。对于专科生来说&#xff0c;专升本无疑是一次改变命运、开启人生新征程的重要机遇。 一、专升本的价值与意义 &#xff08;一&#xff09;学历提升当你通过专升本考试&#xff0c;成功踏入本科院校的大门&#xff0c;你将获得更高…

【Word原件测试资料合集】软件系统功能测试方案,软件测试方案(整体方案),软件测试文档-测试计划模版(功能与性能),软件测试流程

一、 前言 &#xff08;一&#xff09; 背景 &#xff08;二&#xff09; 目的 &#xff08;三&#xff09; 测试目标 &#xff08;四&#xff09; 适用范围与读者对象 &#xff08;五&#xff09; 术语与缩写 二、 软件测试实施流程 &#xff08;一&#xff09; 测试工作总体流…

【uniapp】实现触底加载数据

前言&#xff1a;实现界面触底数据加载。后端接口得支持翻页传参&#xff08;本案例使用django&#xff09; 1、后端接口 1.1 封装翻页公共方法standardPagination.py # -*- coding: utf-8 -*- # Time : 2024/10/15 13:15 # Author : super # File : standardPaginat…

idea2024年版本

最简单安装2024.2版本idea 内带安装教程 ** 下载链接&#xff1a;https://pan.quark.cn/s/ab24afbaa43f 提取码&#xff1a;KHrq

《计算机视觉》—— 基于PyCharm中的dlib库实现人脸关键点定位

文章目录 1. 安装必要的库2. 下载dlib的人脸检测器和关键点预测器模型3. 编写代码 人脸关键点定位是指通过计算机视觉技术&#xff0c;识别和定位人脸图像中的关键点&#xff0c;如眼睛、鼻子、嘴巴等特定位置。这些关键点的准确定位对于人脸识别、表情分析、姿态估计等应用具有…

天地伟业NVR管理工具EasyNVR平台多个NVR同时管理运行后日志一直在打印error

视频安防监控平台天地伟业NVR管理工具EasyNVR可支持设备通过RTSP/Onvif协议接入&#xff0c;并能对接入的视频流进行处理与多端分发&#xff0c;包括RTMP、RTSP、WS-FLV、HTTP-FLV、WebRTC、HLS等多种视频流格式。平台可提供视频实时监控直播、云端录像、录像检索、云存储与回看…

基于SSM的药品商城系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

沉浸式娱乐新纪元,什么是5G+实时云渲染VR大空间?

近年来&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在娱乐、教育、医疗等多个领域展现出巨大的潜力&#xff0c;尤其是VR大空间体验&#xff0c;更是以其沉浸式和互动性的特点&#xff0c;迅速成为市场的新宠。据Statista数据显示&#xff0c;2023年&#xff0c;全球虚…

Lumerical学习——资源管理和运行模拟

一、资源管理&#xff08;Resource Manager&#xff09; 在模拟计算前必须对计算资源进行配置。采用资源管理器可以完成这项任务。单击主工具条的“资源&#xff08;Resources&#xff09;”按钮&#xff08;见上图&#xff09;就可以打开资源管理器。通常每个计算机只需设置一…

【含文档】基于Springboot+Vue的仓库管理系统设计与实现(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…