数据结构第一节 递归

Posted Zack-Scu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构第一节 递归相关的知识,希望对你有一定的参考价值。

  分支转向是算法的灵魂;函数和过程及其之间的相互调用,是在经过抽象和封装之后,实现分支转向的一种重要机制;而递归这是函数和过程调用的一种特殊形式,即允许函数进行自我调用。

  递归的价值在于,许多应用问题都可简洁而准确地描述为递归形式。

  递归也是一种基本而典型的算法设计模式。这一模式可以对实际问题中反复出现的结构和形式做高度概括,并从本质层面加以描述与刻画,进而导出高效的算法。从程序结构的角度,递归模式能够统筹纷繁多变的具体情况,避免复杂的分支以及嵌套的循环,从而更为简明的描述和实现算法,减少代码量,提高算法的可读性,保证算法的整体效率。

线性递归

int sum(int A[], int n) { //数组求和算法(线性递归版) 
    if(n < 1) //平凡情况,递归基
        return 0; //直接(非递归式)计算
    else
        return sum(A, n -1) + A[n - 1];//递归:前n-1项和,再累积 第 n -1 项 
}

  减而治之

    线性递归的模式,往往对应于所谓减而治之(decrease-and-conquer)的算法策略:递归没深入一层,待求解问题的规模都缩减一个常数,直至最终蜕化为平凡的小(简单)问题。

    按照减而治之策略,此处随着递归的深入,调用参数将单调地线性递减。因此无论最初输入的n有多大,递归的总次数都是有限的,故算法的执行迟早会终止,即满足有穷性。当抵达递归基时,算法将执行非递归计算。

void reverse( int* A, int lo, int hi) { //数组倒置(多递归基递归版) 
    if(lo < hi){
        swap(A[lo], A[hi]); //交换A[lo]和A[hi] 
        reverse(A, lo + 1, hi -1); //递归倒置A(lo, hi) 
    }// else 隐含了两种递归基 
}

递归消除

void reverse( int* A, int lo, int hi){ //数组倒置,直接改造得到的非递归版 
    while( lo < hi){
        swap(A[lo], A[hi]);//交换A[lo]和A[hi] 
        lo ++; hi --;//收索待倒置区间 
    }
} 

二分递归

  分而治之:将大的问题分解为若干规模更小的问题,再通过递归机制分别求解。这种分解持续进行,直到子问题规模缩减至平凡情况。这也就是所谓的分而治之(divde-and-conquer)。

int sum( int A[], int lo, int hi){//数组求和方法(二分递归版) 
    if(lo == li)//如遇到递归基(区间长度已将为1),则 
        return A[lo];//直接返回该元素
    else{
        int min = (lo + hi) >> 1; //以居中单元为界将原区间一分为2
        return sum(A, lo, mi) + sum(A, mi + 1, hi); //递归对 各子数组求和,然后合计。 
    } 
} 

 

   

 

以上是关于数据结构第一节 递归的主要内容,如果未能解决你的问题,请参考以下文章

递归与分治策略-第一节:递归和典型递归问题

第一节数据绑定

动态规划-第一节3:动态规划之使用“找零钱”问题说明最优子结构如何解决

flutter 分层数据显示 类似于第一章的第一节显示 网络请求渲染 开源代码

动态规划-第一节2:动态规划之使用“斐波那契数列”问题说明重叠子问题如何解决

蓝桥杯DFS正确入门方式 | DFS + 递归与递推习题课(上) | 一节课教你爆搜!——学习笔记