自学内容网 自学内容网

函数(递归)

递归:程序调用自身编程技巧称为递归。

       在学习递归前需要粗略的了解一下内存,内存分为三类,分别是栈区、堆区和静态区。对于栈区来说,每调用一次函数都会为本次函数开辟一块空间,然而栈区也是有空间限制的,随即函数调用存在限制条件(当满足这个限制条件是递归便不再继续),且每次递归调用后越来越接近这个限制条件。超过这个限制会出现栈溢出的现象。

现在写一个简单的代码看一下栈溢出会出现怎么样的现象。

int main()
{
printf("NX\n");
main();
return 0;
}

递归题目类型(既可以用递归也可以用非递归(简称迭代))

        1.打印一个数字的每一位且按照顺序。例:1024->1 0 2 4 ;

递归法

       递归是由里往外,先执行最里层的函数,函数执行完再逐渐返回调用的函数直至函数全部执行完返回到主函数里。这个题目就是不断地取余取模,一直重复这两个操作。它可以通过抹去尾位不断调用函数直至打印最高位,下面这个图演示了调用函数的过程:

 代码实现:

void print_digit(int n)
{
if (n)
{
print_digit(n / 10);
printf("%d ", n % 10);

}
}

int main()
{
int n = 0;
scanf("%d", &n);
print_digit(n);
return 0;
}

 迭代法

       这个方法需要抹去最高位数并打印出来,在这之前需要知道这个数的位数。接着对这个数进行相同位数取模、打印,取余减小位数为了打印下一位数字,这个相同位数在打印中不断变化(减小一位),然后就是重复之前的操作。

       举一次例子:通过计算得到1024是一个四位的数字,然后计算出就是相同位数1000,先取模1024/1000并打印数字1,最高位就打印好了,其次就是取余1024%1000=24将其值赋值给n,相同位数随即也要减小一位1000/10;然后就是while循环重复。

代码实现: 

int digit(int n)
{
int count = 0;
while (n)
{
n = n / 10;
count++;
}
return count;
}

int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int count = 0;
int ret = 1;
count = digit(n);//调用函数的原因是不改变n的值(利用形参不改变实参的值)
for (i = 1; i < count; i++)
{
ret = ret * 10;//计算相同位数
}
while (n)
{
printf("%d ", n / ret);
n = n % ret;//取余
ret = ret / 10;//为了相同位数取模
}
return 0;
}
       2.实现n的k次方。例:2 3->8;

递归法

       限制条件是(k>0)满足调用函数,不满足返回1。下图展示:

代码实现: 

int factorial(int n, int k)
{
if (k > 0)
{
return n * factorial(n, k - 1);
}
else
{
return 1;
}
}

int main()
{
int n = 0;
int k = 0;
scanf("%d %d", &n, &k);
int sum = factorial(n, k);
printf("%d\n", sum);
return 0;
}

迭代法

       通过循环相乘有点类似累乘,代码也更少一点。代码实现:

int main()
{
int n = 0;
int k = 0;
int i = 0;
int num = 1;
scanf("%d %d", &n, &k);
for (i = 1; i <= k; i++)
{
num = num * n;//n的k次方
}
printf("%d\n", num);
return 0;
}
       3.斐波那契数。例:1,1,2,3,5,8,13,......

递归法

       限制条件(n<3)。满足返回1,不满足调用函数直至返回一个数字。下面是第五个斐波那契数需要调用的斐波那契数,仔细看会发现有一些斐波那契数重复计算或调用(3,2,1),这大大增加计算的时间,假设需要计算一个很大很大的斐波那契数那重复计算的次数会更多,所以有时候并不是代码越简单越好,或任何场景使用递归都不是明智之举,需要具体问题具体分析。

代码实现: 

int fibonacci(int n)
{
if (n < 3)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}


int main()
{
int n = 0;
scanf("%d", &n);
int ret = fibonacci(n);
printf("%d\n", ret);
return 0;
}

迭代法 

 简单明了的表明意图,循环直接算斐波那契前两项,通过不断复制避免重复计算。代码演示:

int main()
{
int n = 0;
int i = 0;
int a = 1;
int b = 1;
long long c = 1;//考虑斐波那契数会是一个巨大的数
scanf("%d", &n);
while (n > 2)
{
c = a + b;
a = b;
b = c;
n--;//循环条件
}
printf("%d\n", c);
return 0;
}


原文地址:https://blog.csdn.net/2402_84815218/article/details/140497458

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!