C语言—经典递归算法

          递归函数的“灵魂”在于其核心思想:将一个复杂的问题分解为更简单的子问题,并通过函数自身调用来解决这些子问题,直到达到一个基本情况(或边界条件),从而终止递归。

1.使用递归算法求阶乘

#include <stdio.h>
int main(int argc,char* argv[])
{
        int n = 5;                  //定义所求的阶数,也可以使用scanf函数获取阶数

        int result = jie(n);
        printf("result  = %d\n",result);
        return 0;
}

int jie(int n){             //定义函数,返回值是int型,调用函数需要传入参数
        if(1 == n)
                return 1;         // 递归终止条件
        return n*jie(n-1);         
}

结果为: 

2.使用递归求斐波那契数列

 斐波那契数列是一个经典的数列,定义如下:

  • 数列的前两项为 0 和 1(有时也可以从 1 和 1 开始)。
  • 从第三项开始,每一项都是前两项的和。
  • 前十项的斐波那契数列为:1, 1, 2, 3, 5, 8, 13, 21, 34,55.
#include <stdio.h>                                                                                  

int fei(int n1,int n2,int n);      //函数声明

int main(int argc,char* argv[])
{ 
    int n1 = 1;          
    int n2 = 1;
    int n;
    
    printf("please input n:");
    scanf("%d",&n);
    
    if(n <= 2)                   //判断n的值,是否直接输出前两项
        for(int i=0;i < n;i++)
            printf("%d,",n1);
    else{
        printf("%d,%d,",n1,n2);  
        for(int i =3;i <= n;i++)
            printf("%d,",fei(n1,n2,i-2));
    }
    printf("\n");
     return 0;
}

int fei(n1,n2,n){               //递归函数
    if(1 == n)
        return n1+n2;
    return fei(n2,n1+n2,n-1);
}
                                                                             

结果为:


                                             

3.  使用指针和递归实现合并排序

1. 分解(Divide)

  • 递归基准:首先判断当前子数组是否只有一个元素。如果是,则返回,因为单个元素是有序的。
  • 计算中间索引:将当前数组的左右边界(left 和 right)确定,并计算中间索引 mid

2. 递归调用

  • 递归排序:对左半部分(从 left 到 mid)和右半部分(从 mid + 1 到 right)分别进行递归调用。这样会继续将数组逐步分解,直到每个子数组只有一个元素。

3. 合并(Merge)

  • 创建临时数组:在合并阶段,使用两个临时数组存储左右子数组的元素。
  • 指针比较:通过指针遍历这两个临时数组,比较元素的大小,将较小的元素依次放回原数组中。
  • 拷贝剩余元素:如果一个子数组中的元素已经全部被取出,直接将另一个子数组中剩余的元素拷贝到原数组。

4. 返回结果

  • 递归完成后,原数组就会被排序。
#include <stdio.h>                                                                                  

// 合并两个已排序的子数组
void merge(int *arr, int left, int mid, int right) {
        int n1 = mid - left + 1, n2 = right - mid;
        int L[n1], R[n2];

        for (int i = 0; i < n1; i++) L[i] = arr[left + i];
            for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];
        int i = 0, j = 0, k = left;
        while (i < n1 && j < n2) {
            arr[k++] = (L[i] <= R[j]) ? L[i++] :R[j++];
        }
        while (i < n1) arr[k++] = L[i++];
        while (j < n2) arr[k++] = R[j++];
}

// 主函数进行合并排序
void merge_sort(int *arr, int left, int right) {
        if (left < right) {
            int mid = left + (right - left) / 2;
            merge_sort(arr, left, mid);
            merge_sort(arr, mid + 1, right);
            merge(arr, left, mid, right);
                                                }
}

// 主程序
int main() {
        int arr[] = {38, 27, 43, 3, 9, 82, 10};
        int size = sizeof(arr) / sizeof(arr[0]);

        for (int i = 0; i < size; i++) printf("%d ", arr[i]);
        printf("\n");

        merge_sort(arr, 0, size - 1);

        for (int i = 0; i < size; i++) printf("%d ",arr[i]);
        printf("\n");

        return 0;
}                                                                                                   

                                                                                                                                                                           
                                                                                            
  1. merge 函数:合并两个已排序的子数组,使用指针来访问数组元素。
  2. merge_sort 函数:递归地将数组分成两半,并排序后合并。
  3. main 函数:程序入口,定义数组并输出排序前后的结果

                    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值