编程语言
首页 > 编程语言> > 《数据结构》算法学习

《数据结构》算法学习

作者:互联网

《数据结构》算法--递归与数学归纳法

递归与数学归纳法有着本质上的联系:

1.数列

 数列也是一种特殊的数学归纳法,其递推公式、前n项求和都体现了数学归纳法和递归的
 思想。

2.数学归纳法

 步骤:(1)假设n = 1,结论成立;
    (2)假设n = k时,结论成立,根据递推公式,求证n = k+1时结论也成立;

3.递归

步骤:(1)找递归出口,类似n = 1或初始化的状态;
   (2) 找递归嵌套,同递推公式,找出第k项与第k-1项之间的关系;
   (3)完成上面两步,再单纯考虑一个完整的算法周期的具体实现,后面的套娃让
      程序自己去完成;

4.三者之间的关系如下表:

思想初始状态关系式相互关系
数列a1 = k,(k为已知数)an = f(a(n-1))数列首项为递归入口,递推公式为递归的函数调用
数学归纳法n=1时,结论成立假设n=k时结论成立,证明n=k+1时结论也成立n=1为递归入口,k-->k+1的论证关系为递归的函数调用
递归入口(一般元素个数为1)递归关系,函数一层层的调用函数调用看作数列递推公式

5.示例

example 1:求数组的所有元素之和;
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
//3.定义好递归出口和嵌套公式之后,整段函数只是单纯考虑一个完整的算法周期的实现:
//  即把sum分割成arr[L]与ArrSum[arr, L+1, R]之和,这边正确实现之后,后面的套娃让程序自己去完成;
//  L为第一个元素位序,R为最后一个元素的位序;
int ArrSum(int arr[], int L, int R){
    int sum;
    //1.递归出口,如同数学归纳法中初始状态:n=1的情况;
    if (L == R)
        sum = arr[L];
    else
    //2.递归嵌套,同递推公式,找出L和L+1的关系
        sum = arr[L] + ArrSum(arr, L+1, R);  
    return sum;
}
int main(){
    int arr[5] = {5, 5, 5, 5, 10};
    int s = ArrSum(arr, 0, 4);
    
    printf("s = %d\n", s);
    return 0;
}

example 2:求数组中所有元素的最大值;
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
/*int FindMax(int arr[], int len){
    int max = arr[0];
    for (int i=0; i<len; i++){
        if (arr[i] > max)
            max = arr[i];
    }
    return max;
}*/

//3.两数比大小的具体实现,单纯考虑一个完整的算法周期的实现
//  L为第一个元素位序,R为最后一个元素的位序;
int FindMax2(int arr[], int L, int R){
    //1.递归出口
    if (L == R)
        return arr[L];
    else{
        int a = arr[L];
        int b = FindMax2(arr, L+1, R);
        //2.把套娃第二层当做一个整体,与a进行比较
        if (a > b)
            return a;
        else
            return b;    
    }    
}
int main(){
    int arr[10] = {5, 6, 10, 15, 10, 4, 23, 13, 8, 9};
    int m;
    m = FindMax2(arr, 0, 9);
    printf("m = %d\n", m);
    return 0;
}

example3:冒泡排序(从小到大);

//冒泡排序的递归实现:从小到大
#include<stdio.h>
#include<stdlib.h>
//3.两数比大小的具体实现
//  L为第一个元素位序,R为最后一个元素的位序;
void Bubble(int arr[], int L, int R){
    int temp;
    //1.递归出口
    if (L == R)
        return;
    else{
        for (int i=L; i<=R-1; i++){
            if (arr[i] > arr[i+1]){
                temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }   
        //2.进行完一个完整的比较周期(第一轮比较之后最大数在最右边)之后,
        //  数组就被分成了Bubble(arr, L, R-1)和arr[R]两个部分
        //3.把剩下的部分继续用递归实现
        Bubble(arr, L, R-1);
    }   

    return;
}
int main(){
    int arr[10] = {5, 6, 11, 15, 10, 4, 23, 13, 8, 27};
    Bubble(arr, 0, 9);
    for (int i=0; i<10; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

example4:求两数的最大公约数(思想:辗转相除法)
在这里插入图片描述

//求两数的最大公约数(辗转相除法,若最后的余数为零则最后的被除数为最大公约数)
#include<stdio.h>
#include<stdlib.h>
int gcd(int a, int b){
    int r = a % b;
    /*两数相除:若余数为零,则被除数是最大公约数;
               若余数不为零,则它们的最大公约数即是被除数与余数的最大公约数;*/
    //递归出口
    if (r == 0)
        return b;
    else
       return gcd(b, r);
}

int main(){
    int a, b;
    scanf("%d", &a);
    scanf("%d", &b);
    int g = gcd(a, b);
    printf("%d\n", g);
    return 0;
}

标签:arr,include,return,递归,int,学习,算法,归纳法,数据结构
来源: https://blog.csdn.net/zcj_jarry/article/details/113097179