C语言---函数递归

一.基础概念

1.1函数递归的定义

递归:递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。

递归的思想: 把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再 被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩(这种思考方式十分重要)的过程。 递归中的递就是递推的意思,归就是回归的意思。

 1.2递归的限制条件

递归在书写的时候,有2个必要条件:

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

• 每次递归调⽤之后越来越接近这个限制条件。

1.3递归的优缺点

优点:函数递归只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
缺点:①如果函数递归使用不恰当,会导致栈溢出,因为每一次函数调用都会在栈区上申请内存空间。②每一次函数递归(函数调用)都会在函数栈帧上开辟一块空间,所谓的压栈。这样会大大降低我们代码的执行效率。
 

 二.基础函数递归例题

2.1史上最简单的递归

#include <stdio.h>
int main()
{
 printf("xixi\n");
 main();//main函数中⼜调⽤了main函数
 return 0;
}

上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本形式,不是为了解决问 题,代码最终也会陷⼊死递归,导致栈溢出(Stack overflow),就体现了缺点2.

2.2打印一个数的每一位

题目描述:

输入一个整数,按照顺序打印它的每一位,例如,输入:1234,输出1 2 3 4

 解题思路:我们首先要思考如何把问题⼤事化⼩,把Print(1234) 打印1234每⼀位,拆解为⾸先Print(123)打印123的每⼀位,再打印得到的4 把Print(123) 打印123每⼀位,拆解为⾸先Print(12)打印12的每⼀位,再打印得到的3 直到Print打印的是⼀位数,直接打印就⾏。

如果输入的数字是小于10的,要如何得到它的每一位,我们可以想到是将它取余得到,这种输入输出数字的题,我们一定要想到取模和取余的方法,并且要有限制条件,每次函数递归后,都会越来越接近这个值。


设n为1234

print(1234/10) + 1234%10 (=4)
print(123/10) + 123%10(=3
print(12/10) + 12%10(=2

当n最后为1时,不满足我们给定的限制条件n>9时,即打印1%10得到1。

以此类推

Print(1234)

==>Print(123) + printf(4)

==>Print(12) + printf(3)

==>Print(1) + printf(2)

==>printf(1)

代码实现

#include<stdio.h>
int Print(int a)
{
	if (a>9)
	{
		Print(a / 10);
	}
		printf("%d ", a % 10);


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

 画图推演

 2.3BC171 牛牛的Hermite多项式

 代码描述

#include <stdio.h>
int Fun(int a,int b)
{
    if(a==0)
    return 1;
    else
     if(a==1)
     {
        return 2*a;
     }
     else 
     return 2*b*Fun(a-1,b)-2*(a-1)*Fun(a-2,b);
}
int main() {
   int n=0,x=0;
   scanf("%d%d",&n,&x);
   printf("%d",Fun(n,x));
    return 0;
}

三.经典递归题 

 3.1求第n个斐波那契数递归和非递归的实现

计算斐波那契数递归实现求第n个斐波那契数
例如:
输入:5 输出:5
输入:10, 输出:55
输入:2, 输出:1

解题思路:斐波那系数是前两项加起来等于后一项:1,1,2,3,5,8,13…,所以我们可以以n<=2为限制条件,当n=1或2时,返回1,然后到n=3项时就是n=1项和n=2项之和,然后依次往后推,即Fib(n)就是Fib(n-1)和Fib(n-2)之和

int Fib(int n)
{
 if(n<=2)
 return 1;
 else
 return Fib(n-1)+Fib(n-2);
}

画图推演

 

 非递归实现

int Fib(int n)
{
 int a = 1;
 int b = 1;
 int c = 1;
 while(n>2)
 {
 c = a+b;
 a = b;
 b = c;
 n--;
 }
 return c;
}

递归和非递归的方式,我们可以发现,递归在求比较大的斐波那契数时,递归程序会不断的展开,在展开的过程中,会有重复计算,⽽且递归层次越深,冗余计算就会越多。因此,我们不能什么都用递归来解决问题。

3.2BC166 小乐乐走台阶

描述

小乐乐上课需要走n阶台阶,因为他腿比较长,所以每次可以选择走一阶或者走两阶,那么他一共有多少种走法?

输入描述:

输入包含一个整数n (1 ≤ n ≤ 30)

输出描述:

输出一个整数,即小乐乐可以走的方法数。

解题思路:当只有一阶台阶时只有1种走法,二阶台阶时,有两种走法,因此我们可以得到当台阶数大于2时,有Fun(n-1)+Fun(n-2)种走法。此题是求第n个斐波那契数的演变。

代码解释:

#include <stdio.h>
int Fun(int n)
{
    if(n<2)
    
        return 1;
    
    else 
        return Fun(n-1)+Fun(n-2);
    
}
int main() {
   int a=0;
   scanf("%d",&a);
   printf("%d",Fun(a));
    return 0;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言是一种广泛应用于系统编程和嵌入式开发的高级编程语言函数指针是C语言中的一个重要概念,它可以指向函数,并且可以通过函数指针来调用函数。快速排序算法是一种常用的排序算法,它的核心思想是通过分治的策略将一个大问题分解为多个小问题,并通过递归的方式解决这些小问题。 下面是C语言中使用函数指针实现快速排序算法的示例代码: ```c #include <stdio.h> // 交换两个元素的值 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 快速排序的分区函数 int partition(int arr[], int low, int high) { int pivot = arr[high]; // 选取最后一个元素作为基准 int i = (low - 1); // 定义一个指针,用于指向小于基准的元素 for (int j = low; j <= high - 1; j++) { if (arr[j] < pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } // 快速排序函数 void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); // 将数组分区,并获取分区点的位置 quickSort(arr, low, pi - 1); // 对分区点左边的子数组进行快速排序 quickSort(arr, pi + 1, high); // 对分区点右边的子数组进行快速排序 } } // 打印数组元素 void printArray(int arr[], int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = {10, 7, 8, 9, 1, 5}; int n = sizeof(arr) / sizeof(arr[0]); printf("原始数组:"); printArray(arr, n); quickSort(arr, 0, n - 1); printf("排序后的数组:"); printArray(arr, n); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值