【C语言】带你玩转递归,迭代算法1

简介: 【C语言】带你玩转递归,迭代算法

前言

不像加减乘除,我们求学期间就已经见识过多次了,而大多数初学者在此之前可能都从未了解接触过递归思想,这使得很难上手递归算法,今天我希望能尽我所能结合画图已经例题的方法把递归算法讲解的通俗易懂,帮助大家入门


废话不多说了,我们开始今天的内容

一.什么是递归?

程序调用自身的编程技巧称为递归( recursion)。

递归做为一种算法在程序设计语言中广泛应用。 递归算法通常指一个过程或函数在其定义或说明中直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。(也就是说我们现在学的需要使用递归的场景大多数通过循环也能解决,在下面介绍的例子中会用循环也实现一遍)

递归的主要思考方式在于:把大事化小

当你在使用递归时遇到思考瓶颈,请牢记大事化小的思想!!

二.递归的两个必要条件

1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。

2.每次递归调用之后越来越接近这个限制条件。

当你不满足这两个条件的任意一条时,程序会陷入死循环

当你的递归写出bug时,往往是没考虑上面这两个条件或者条件设置有误,调试时多想想递归条件最好能够画下图帮助自己理解。


三.配合实例讲解

打印整型数据的每一位

实例一:

接受一个整型值(无符号),按照顺序打印它的每一位。

例如:

输入:1234,输出 1 2 3 4


代码如下:

#include <stdio.h>
void print(int n)
{
if(n>9)//如果不大于9直接打印当前n的值即可
{
print(n/10);
}
printf("%d ", n%10);
}
int main()
{
int num = 1234;
print(num);
return 0;
}

我们想要把一个四位数甚至更多位的数每一位给剥离出来,首先要想到的是怎么得到每一位

我们知道,对10取余%就可以得到这个数的个位的数,而除以10就可以把这一位给消去,此时我们就可以这样实现(以下把n当作一个四位数举例)

先让n对10%得到此时这一位的数,然后将n/10来到下一位,再让n对10%得到这位数继续朝下进行直至n对10%等于0,说明此时n是个小于10的数只剩下它需要取了,取下它结束递归即可

画图解释

递归的递就是传递的意思,而归的意思是回归

fa73e68a67144951899245cbd43bb120.png

这就是递归!

解释完了递归在这段代码的应用,我们来讲讲这个代码中出现的问题

当我们中用户某天突发奇想输入了一个负数进去会发生什么呢?

61418d7a5d954fd185449c1edf39bda0.png

我们这个程序设定的条件是只针对正数的,要想输入一个负数也能打印就得这样修改代码

void print(int n)
{
  if (n > 9)//如果不大于9直接打印当前n的值即可
  {
    print(n / 10);
  }
  else if (n < -9)
  {
    print(n / 10);
  }
  printf("%d ", n % 10);
}
int main()
{
  int num = -1234;
  print(num);
  return 0;
}

或者把我们传入的int改为一个无符号整型

void print(unsigned int n)
{
  if (n > 9)//如果不大于9直接打印当前n的值即可
  {
    print(n / 10);
  }
  /*else if (n < -9)
  {
    print(n / 10);
  }*/
  printf("%d ", n % 10);
}

这里虽然都是非常简单的地方,但我想提醒大家的是,无论在递归或者任何其他程序的编写中我们都得尽可能考虑各方面的情况,在以后的程序猿工作中,我们要知道用户是不总是照着你的指示来使用程序的,我们得尽可能保证程序的避免上面这种bug。

循环实现

//判断输入数字位数
#include<math.h>
int Strlen(unsigned int n)
{
  int count = 0;
  while (n / 10)
  {
    count++;
    n /= 10;
  }
  return count;
}
void print(unsigned int n)
{
  int i = 0;
  int ret = Strlen(n);
  if (n > 9)
  {
    for (i = ret; i > 0; i--)
    {
      int m = pow(10, i);
      printf("%d ", n / m);
      n %= m;
    }
  }
  printf("%d", n);
}
int main()
{
  int num = 123456789;
  print(num);
  return 0;
}

我们先来看看效果

a9d18c96e5df4d0aa5d31f050d5d31e4.png


说实话,同样实现一个功能递归比循环简单多了,从代码的行数就能看出来。这就是我们使用递归算法的意义


求字符串长度

实例二

编写函数不允许创建临时变量,求字符串的长度。

#include <stdio.h>
int Strlen(const char*str)
{
if(*str == '\0')//是个空字符串
return 0;
else
    return 1+Strlen(str+1);//每次递归让Strlen朝后移动一位直至遇到"\0"不满足递归条件
}
int main()
{
char *p = "abcde";
int len = Strlen(p);
printf("%d\n", len);
return 0;
}

咱们还是画个图理解吧

3de357571fd4427f9d93f5aadea699fa.png


结合咱们这个图理解起来就比较简单啦,我希望以后你自己写的时候在有弄不清逻辑时也能画一个类似的图来理解。

循环实现

int Strlen(char* s)

int Strlen(char* s)
{
  int count = 0;
  while (*s != '\0')
  {
    count++;
    s++;
  }
  return count;
}
int main()
{
  char* p = "abcde";
  int len = Strlen(p);
  printf("%d\n", len);
  return 0;
}

结合咱们这个图理解起来就比较简单啦,我希望以后你自己写的时候在有弄不清逻辑时也能画一个类似的图来理解。

目录
相关文章
|
1月前
|
自然语言处理 算法 搜索推荐
C语言中谈论算法
C语言中谈论算法
10 0
C语言中谈论算法
|
17天前
|
算法
算法系列--递归(一)--与链表有关(上)
算法系列--递归(一)--与链表有关
27 0
|
3天前
|
算法
数据结构与算法-递归思想
数据结构与算法-递归思想
6 0
|
14天前
|
缓存 算法 Python
python算法对音频信号处理Sonification :Gauss-Seidel迭代算法
python算法对音频信号处理Sonification :Gauss-Seidel迭代算法
10 0
|
21天前
|
存储 算法 搜索推荐
【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)
【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)
|
26天前
|
算法 C语言
【算法与数据结构】 C语言实现单链表队列详解2
【算法与数据结构】 C语言实现单链表队列详解
|
26天前
|
存储 算法 C语言
【算法与数据结构】 C语言实现单链表队列详解1
【算法与数据结构】 C语言实现单链表队列详解
|
26天前
|
C语言 索引
【C语言】C语言⻘蛙跳台阶问题--递归问题
【C语言】C语言⻘蛙跳台阶问题--递归问题
|
1月前
|
存储 编解码 自然语言处理
【软件设计师备考 专题 】深入理解数据压缩、递归和图的相关算法
【软件设计师备考 专题 】深入理解数据压缩、递归和图的相关算法
64 0
|
1月前
|
存储 机器学习/深度学习 算法
C语言代码实现数据结构与算法
以上代码中,哈希表使用链表解决哈希冲突,每个链表节点包含一个键值对。hash函数用于计算键值对应的哈希值,insert函数用于向哈希表中插入一个键值对,若当前位置为空,则直接插入;否则,将新节点插入到链表末尾。search函数用于在哈希表中查找指定键值的值,若存在则返回其值,否则返回-1。
32 1