• 数据结构第一节 递归


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

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

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

    线性递归

    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); //递归对 各子数组求和,然后合计。 
        } 
    } 

       

  • 相关阅读:
    对数线性模型与线性链条件随机场
    25匹马,5个跑道,每个跑道最多能有1匹马进行比赛,最少比多少次能比出前3名?前5名?
    SVM 与 LR的异同
    EM算法简易推导
    K-means算法的优缺点
    自助采样包含训练集里63.2%的样本?
    指数加权移动平均
    oracle 对于用户的相关操作
    docker 安装 maven 私有库 nexus3
    idea 自动注入@Autowired 警告 Field injection is not recommended 关闭
  • 原文地址:https://www.cnblogs.com/zangkuo/p/8111235.html
Copyright © 2020-2023  润新知