C语言第入门——第十六课

目录

一、分治策略与递归

二、递归

1.求解n的阶乘

2.输入整数、倒序输出

3.输入整数、正序输出 

4.计算第n位Fibonacci数列

​编辑5.无序整数数组打印

6.找到对应数组下标 


一、分治策略与递归

在我们遇到大问题的时候,我们的正确做法是将它分解成小问题,然后一个小问题一个小问题解决,这样的策略就是分治策略。

递归是分治策略的一种方式,可以不断地通过自己调用自己来将问题规模逐渐缩小,从而解决问题。

分治策略的特征:

①大规模问题化成小规模问题容易被解决掉

②大规模问题能够被划分为多个相同的小规模问题

③这些小规模问题的解组合起来是大问题的解

④小规模问题是相互独立的

举个例子:

皇帝让你数10个谷仓的米粒,问题规模太大,你可以找100个工人,每人分上相同重量的米进行数,每个人的数量相加就是最终米粒的数量。

这就是一个典型的分治策略问题,将大规模转化为小规模问题,而且是满足上面分治策略的四条特征的。

分治策略不光在我们算法中需要使用,我希望转化成我们的思维模式,帮助我们更好的解决生活中的问题。

二、递归

递归包含两个过程:递推和回归,递推逐层调用,直到递推终止条件满足,再逐层回归。

递归和普通函数调用类似,需要开辟栈帧空间,它只有满足中止条件逐层回归的时候,上一层的函数的栈帧空间才会被释放。注意,不存在无限递归的函数,因为栈帧空间是有限的,所以不能无限调用函数,开辟空间。

递归分为直接递归和间接递归。

直接递归:在函数执行的时候调用函数自身。

间接递归:在函数执行过程中调用其他函数,再调用函数自身。

一般不推荐使用间接递归,因为很容易递推错误。

1.求解n的阶乘

代码如下:

int fabi(int n)
{if (n == 1) return 1;int sum = fabi(n-1)*n;return sum;
}int main()
{int n = 0;scanf("%d", &n);int sum =fabi(n);printf("%d", sum);
}

分析:我们将代码复制多份便于观看,但其实只有一个代码哦。

我们这里取n=4,第一次进入到fabi()函数中,n!=1,执行下一条语句fabi(n-1)*n,也就是fabi(3)*4。

然后我们再次调用函数fabi(),此时n=3,我们进入到函数体中n!=1,执行下一条语句fabi(2)*3。

此时我们再次调用fabi()函数,此时n=2,n!=1,执行fabi(1)*2。

这里再次调用fabi()函数,此时n==1,所以我们return 1。

返回到上一层,我们继续执行,此时这条语句为sum = 1*2,我们返回1*2,然后我们继续回归上一层函数,sum = 3*2*1,然后我们再回归,最后得到sum =4*3*2*1,回归结束。

下面第一张是我画的示意图,如果看不清楚再看下面第二张老师画的图,老师画的比较清晰。

红色的线代表递推过程,绿色的线代表回归过程。

 下面解释一下栈帧的动态变化情况。

在每次递推调用函数的时候,程序开辟栈帧空间,在回归的时候再一层层释放掉。

2.输入整数、倒序输出

输入一个整数(无符号整型),使用递归算法将整数倒序输出。

void Show(unsigned int n)
{if (n == 0) return ;else{printf("%d", n % 10);Show(n / 10);}
}
int main()
{unsigned int n = 0;scanf("%d", &n);Show(n);
}

逻辑图如下,变量和函数定义不太一样,但是逻辑一致。

3.输入整数、正序输出 

法一:数组法

void Show(unsigned int n)
{	int ar[10] = {0};int i = 0;while (n!=0){ar[i] = n % 10;n = n / 10;i++;}i--;while (i>=0){printf("%d ", ar[i]);i--;}
}
int main()
{unsigned int n = 0;scanf("%d", &n);Show(n);
}

法二:递归法

void Show(unsigned int n)
{if (n == 0) return;else{Show(n / 10);printf("%d", n % 10);}
}
int main()
{unsigned int n = 0;scanf("%d", &n);Show(n);
}

4.计算第n位Fibonacci数列

法一:循环输出

int Fibonna(int n)
{int a = 1;int b = 1;if (n==0) return 0;if (n == 1 || n == 2){return 1;}else{int i = 0;int temp = 0;int result = 0;while (i<n-2){result = a + b;temp = b;b = result;a = temp;i++;}return result;}}
int main()
{int n = 0;scanf("%d", &n);int result = Fibonna(n);printf("%d", result);
}

法二:递归输出

int Fibonna(int n)
{if (n == 0) return 0;if (n == 1|| n == 2){return 1;}else{return (Fibonna(n - 1) + Fibonna(n - 2));}
}
int main()
{int n = 0;scanf("%d", &n);int result =Fibonna(n);printf("%d",result);
}

Q: 使用递归进行输出的时候空间复杂度是2^n,很大,怎么样降低时间复杂度?

A: 想要降低复杂度,主要就是要减少一个递归函数,将递归过程中的值存储下来就能减少相应的复杂程度。

写法一:一定要注意a,b,temp不能每次被调用的时候都初始化,要不然输出的值不正确。

int fac(int n)
{static int a = 1;static int b = 1;static int temp = 1;if (n <= 2) return temp;temp = a + b;b = a;a = temp;fac(n - 1);
}
int main()
{int n = 0;scanf("%d", &n);int result = fac(n);printf("%d", result);
}

写法二:思路一致,只不过老师写的更清楚明了。

int fanc(int n, int a, int b)
{if (n <= 2) return a;else return fanc(n - 1, a + b, a);
}
int fac(int n)
{int a = 1;int b = 1;return fanc(n, a, b);
}
int main()
{int n = 0;scanf("%d", &n);int result = fac(n);printf("%d", result);
}

5.无序整数数组打印

有一个整型数组,数值无序,使用循环和递归打印和查询。

法一:循环打印

void Show_Arr(const int* ar, const int  n)
{if (n < 1 || ar == NULL) return;for (int i = 0; i < n; i++){printf("%d ", ar[i]);}
}
int main()
{const int n = 3;int ar[n] = { 12,23,34 };Show_Arr(ar,n);
}

法二:使用递归打印数组

void Show_Arr(const int* ar, const int  n)
{if (n < 1 || ar == NULL) return;Show_Arr(ar, n - 1);printf("%d ", ar[n - 1]);}
int main()
{const int n = 3;int ar[n] = { 12,23,34 };Show_Arr(ar, n);
}

Q:上述递归代码我可可以将n-1修改成n--吗?请详细说明。

A:不可以修改,后置--是先取值后--,在下面示例中,n=3,n>0,调用函数,调用的新的函数还是n=3的函数,进入到一个循环,直到栈帧空间被填满。

Q:上述递归代码我可可以将n-1修改成--n吗?请详细说明。

A:也不可以修改,前置--是先--再取值,的确可以满足递归调用的逻辑,但是当他进行回归的时候会n的值被更改了,输出的是更改后的n-1,造成数据溢出问题。

6.找到对应数组下标 

法一:循环找数组下标

int FindValue(const int* arr, int n, int value)
{if (n < 1 || arr == NULL)	return 0;int pos = -1;for (int i = 0; i < n; i++){if (arr[i] == value){pos = i;break;}}return pos;
}
int main()
{const int n = 5;int arr[n] = { 10,11,12,13,14 };int val = 0;scanf("%d", &val);int m = FindValue(arr, n, val);printf("%d", m);
}

法二:递归找数组下标

这面这个代码输出的数组下标有问题,一直是-1

int FindValue(const int* br, int n, int val)
{int pos = -1;if (NULL == br || n < 1) return pos;if (br[n-1] == val){pos = n - 1;}else{FindValue(br, n - 1, val);}return pos;
}
int main()
{const int n = 5;int arr[n] = { 10,11,12,13,14 };int val = 0;scanf("%d", &val);int m=FindValue(arr,n,val);printf("%d", m);
}

正确代码 

int FindValue(const int* br, int n, int val)
{int pos = -1;if (NULL == br || n < 1) return pos;if (br[n-1] == val){pos = n - 1;}else{pos =FindValue(br, n - 1, val);}return pos;
}
int main()
{const int n = 5;int arr[n] = { 10,11,12,13,14 };int val = 0;scanf("%d", &val);int m=FindValue(arr,n,val);printf("%d", m);
}

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

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

相关文章

章鱼网络在 NEARCON23 发布 Octopus 2.0

香港时间2023年11月8日12点&#xff0c;章鱼网络举行第15期 Community Call。 我们在10月8日庆祝了章鱼网络主网上线二周年&#xff0c;并参加了激动人心的 Cosmoverse2023 活动。最重要的是&#xff0c;我们在 Octopus 2.0 的开发中取得了重大进展。 11月8日 Community Call …

装修干货|卧室常见3个软装搭配问题。福州中宅装饰,福州装修

引言 作为一名软装设计师&#xff0c;我对卧室的家具及软装布置颇有心得&#xff0c;现在就给你们带来卧室装修设计一些小技巧&#xff1a; 1. 床&#xff1b;衣柜&#xff1b;床头柜的摆放 床的摆放位置非常重要&#xff0c;一般要放在离窗户稍远的地方&#xff0c;避免直接…

Git客户端(TortoiseGit)使用

参考文章&#xff1a; https://www.cnblogs.com/xuwenjin/p/8573603.html 【精选】使用TortoiseGit工具进行开发&#xff08;连接远程仓库进行克隆、拉取、获取、提交、推送、新建/切换/合并分支、解决冲突&#xff09;_tortoisegit连接远程仓库-CSDN博客 tortoise git 拉取…

Postman接收列表、数组参数@RequestParam List<String> ids

示例如下: 接口定义如下: GetMapping(value "/queryNewMoviePath")public List<Map<String, Object>> queryNewMoviePath(RequestParam List<String> ids ) {return service.queryNewMoviePath(ids);}postman中测试如下&#xff1a; http://loc…

【Spring篇】使用注解进行开发

&#x1f38a;专栏【Spring】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出小吉的问题 文章目录 &#x1f33a;原代码&#xff08;无注解&#xff09;&#x1f384;加上注解⭐两个注…

分布式下多节点WebSocket消息收发

1、使用场景 2、疑问 第一次发送请求后&#xff0c;通过N1&#xff0c;W2&#xff0c;到达service2&#xff0c;建立websocket连接。 1、接下来发送的消息&#xff0c;通过Ngixn后和网关gateway后还能落在service2上面吗&#xff1f; 如果不能落在service2上&#xff0c;需要怎…

互联网医院系统:数字化时代中医疗服务的未来

随着数字化时代的发展&#xff0c;互联网医院系统在医疗服务中的作用日益凸显。本文将讨论互联网医院系统的一些关键技术方面&#xff0c;探讨这些技术如何推动医疗服务进入数字化时代。 1. 数据智能与个性化服务 互联网医院系统依赖于大数据分析和人工智能技术&#xff0c;…

Spring Boot使用EhCache完成一个缓存集群

在上一篇在SpringBoot中使用EhCache缓存&#xff0c;我们完成了在Spring Boot中完成了对EhCaChe的使用&#xff0c;这篇&#xff0c;我们将对EhCache的进一步了解&#xff0c;也就是搭建一个EhCache的缓存集群。 集群 在搭建一个EhCache的时候&#xff0c;我们需要先了解&…

2023-11-17 VsCode使用makefile进行多文件编译

点击 <C 语言编程核心突破> 快速C语言入门 VsCode使用makefile进行多文件编译 前言一、一个简单的多文件示例二、makefile基本语法三、VsCode使用makefile总结 前言 要解决问题: C或C可以多文件编译, 意味着需要进行代码组织, 为了方便多文件编译, gnu开发了make工具, …

2018年五一杯数学建模A题徐州潘安湖风景区游览路线设计解题全过程文档及程序

2019年五一杯数学建模 A题 徐州潘安湖风景区游览路线设计 原题再现 徐州是一个老工业基地和资源型城市&#xff0c;煤炭开采历史长达130年。长期煤炭开采在徐州累计形成采煤塌陷区达数十万亩。位于徐州市贾汪区西南部、紧邻马庄的潘安湖湿地公园原来就是徐州最大的、塌陷最严…

实验六:Android的网络编程基础

实验六&#xff1a;Android 的网络编程基础 6.1 实验目的 本次实验的目的是让大家熟悉 Android 开发中的如何获取天气预报&#xff0c;包括了 解和熟悉 WebView、WebService 使用、网络编程事件处理等内容。 6.2 实验要求 熟悉和掌握 WebView 使用 了解 Android 的网络编程…

Hadoop学习总结(MapRdeuce的词频统计)

MapRdeuce编程示例——词频统计 一、MapRdeuce的词频统计的过程 二、编程过程 1、Mapper 组件 WordcountMapper.java package com.itcast.mrdemo;import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; …

网站页头被挂马状态及新增了index.html文件解决思路

今天网站刚新增了篇了文章《从nginx层阻断可执行的php 防止宝塔站点挂马》,整体测试下来还是不靠谱,设置后导致所有PHP文件都打不开了。 经过不断的查看日志和搜索办法总算告一段落,后续待观察。原因如下,多个网站目录新增了index.html文件,看时间是近两天上传的。 网站代…

微信小程序动态生成表单来啦!你再也不需要手写表单了!

dc-vant-form 由于我们在小程序上涉及到数据采集业务&#xff0c;需要经常使用表单&#xff0c;微信小程序的表单使用起来非常麻烦&#xff0c;数据和表单是分离的&#xff0c;每个输入框都需要做数据处理才能实现响应式数据&#xff0c;所以我开发了dc-vant-form&#xff0c;…

【开源】基于Vue.js的社区买菜系统的设计和实现

项目编号&#xff1a; S 011 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S011&#xff0c;文末获取源码。} 项目编号&#xff1a;S011&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.1.1 数据中心模块2.1…

【uniapp】 video视频层级、遮挡其他弹窗或顶部导航 使用nvue覆盖

uniapp 顶部导航和弹窗被video遮挡解决办法 第一步&#xff1a;配置 subNVues {"path": "pages/index/index","style": {"navigationBarTitleText": "uni-app","navigationStyle": "custom","app-…

对话芯动科技 | 助力云游戏 4K级服务器显卡的探索与创新

2021年芯动科技推出了基于IMG BXT GPU IP的风华1号显卡。单块风华1号显卡可在台式机和云游戏中实现4K级别的性能&#xff0c;渲染能力达到5 TFLOPS&#xff0c;如果在服务器中同时运行两块显卡&#xff0c;性能还可翻倍。该显卡是为不断扩大的安卓云游戏市场量身定制的&#xf…

隐私协议 Secret Network 宣布使用 Octopus Network 构建的 NEAR-IBC 连接 NEAR 生态

2023年11月 NearCon2023 活动期间&#xff0c;基于 Cosmos SDK 构建的隐私协议 Secret Network&#xff0c;宣布使用 Octopus Network 开发的 NEAR-IBC&#xff0c;于2024年第一季度实现 Secret Network 与 NEAR Protocol 之间的跨链交互。 这将会是Cosmos 生态与 NEAR 之间的首…

[C国演义] 哈希的使用和开闭散列的模拟实现

哈希的使用和开闭散列的模拟实现 1. 使用1.1 unordered_map的接口1.2 unordered_set的接口 2. 哈希底层2.1 概念2.2 解决哈希冲突 3. 实现3.1 开放寻址法3.2 拉链法 1. 使用 1.1 unordered_map的接口 构造 void test1() {// 空的unordered_map对象unordered_map<int, in…

动态头像如何制作?这个方法请收藏

照片是记录生活的一种方式&#xff0c;但是静态图片有时候不能够完全表达我们的情感。而动态的图片能够让图片以更生动的方式来展示我们的想象力和内心情感。那么&#xff0c;大家知道动态图片制作的方法有哪些吗&#xff1f;使用gif动画制作&#xff08;https://www.gif.cn/&a…