2.1 递归

2019-03-22  本文已影响0人  Aurochsy

Chapter2: 时间复杂度分析、递归、查找与排序

1. 递归

1. 什么是递归

表现:

在函数内部调用函数本身

应用递归的问题特征

一个问题能够划分为更小规模的子问题求解,通过求解更小规模的子问题最终得到问题的答案。更具体地来说,即在本次函数调用中执行一小部分任务,然后传递一个变化了的参数,调用该函数本身执行接下来的任务。

组成:

设计经验:

练习策略:

2. 简单的递归问题示例

2.1 单分支递归

使用递归求阶乘

设计思路:

代码:

int f(int n){
    if(n==1){
        return 1;
    }
    return n*f(n-1);
}
打印 [ i , j ] 之间的整数

即打印 i, i+1 ,..., j

当然这个用一个循环就能解决,这里主要是为了讲解递归的规律

设计思路:

代码:

void printItoJ(int i,int j){
    if(i<j){
        return;
    }
    printf("%d ",i);
    printItoJ(i+1);
}
数组求和

求数组第 i 个元素到最后一个元素的和

int sumArray(int[] arr,int i){
    if(i==arr.length){
        return 0;
    }
    return arr[i]+sumArray[i+1];
}
递归求最大公约数(辗转相除法)
int gcd(int a,int b){
    if(a%b==0){
        return b;
    }
    return gcd(b,a%b);
}
递归进行插入排序
插入排序原理示意
  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤 3,直到找到小于或等于新元素的已排序的元素
  5. 将新元素插入到该元素的位置后
  6. 重复步骤 2~5
插入排序原理示意
非递归的插入排序实现

以从小到大的排序为例:

就是不断把新元素与已排序元素从右到左进行比较

/*按从小到大的插入排序,非递归 */
/*
C++中数组作为函数参数是传址 
*/
void insSort(int arr[],int arrLen){

    //int arrLen = sizeof(arr)/sizeof(arr[0]); 不能在这里计算数组元素个数,因为传入的不是数组而是其地址 
    for(int i=1;i<arrLen;i++){//第一个元素当作已排列序列,从第二个元素开始排列 
        int tmp=arr[i];//未排序的最靠左的元素 
        int j=i-1;//已排序元的最靠后素的下标 
        while(j>=0 && tmp<arr[j]){//当新元素<已排序元素时,已排序元素挨个往后挪 
            arr[j+1]=arr[j];
            j--;            
        }
        arr[j+1]=tmp;//插入新元素 
    }
    //输出排序后的数组 
    for(int i=0;i<arrLen;i++){
        printf("%d ",arr[i]);
    }
    printf("\n");
} 
递归的插入排序

问题的解决思路:

然而设计递归问题时,函数的调用方向应该是问题规模不断变小的,这样函数执行时才是 解决小问题>>解决大问题 的方向,这一点需要注意。

递归形式的解决思路

代码
void insSort2(int* arr,int i){
    
    if(i==0){//第1(下标为0)个元素插入排序的结果 
        return;
    }
    
    insSort2(arr,i-1);//第i个元素的插入排序需要第i-1个元素的插入排序的结果 
    
    /*进行第i个元素的插入排序*/
    int tmp=arr[i];//保存未排序的新元素 
    int j=i-1;//最靠右的已排序元素的下标 
    while(j>=0 && tmp<arr[j]){//当新元素小于已排序元素时,不断将已排序元素挨个往后挪 
        arr[j+1]=arr[j];
        j--;
    } 
    
    arr[j+1]=tmp;//插入新元素 
}

2.2 多分支递归

求斐波那契亚数列第N项

斐波那契亚数列

第n项=第n-1项+第n-2项

int fib(int n){
    if(n==1||n==2){
        return 1;
    }
    return fib(n-1)+fib(n-2);
} 

发现多分支递归会有很多重复项,可以进行优化,之后讨论相关内容

斐波那契亚多分支递归示意

参考资料

[1] 插入排序步骤讲解与实例分析

[2] 插入排序图文讲解

[3] 2.1-2.5 递归与排序解法

[4] C语言通过指针访问一维数组、二维数组、三维数组

上一篇 下一篇

猜你喜欢

热点阅读