采用递归与迭代法思想,分别用java编程去实现欧几里德,斐波那契,牛顿迭代法

Posted 阿啄debugIT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了采用递归与迭代法思想,分别用java编程去实现欧几里德,斐波那契,牛顿迭代法相关的知识,希望对你有一定的参考价值。

前言​

数学中的欧几里德算法斐波那契数列牛顿迭代法求非线性方程的近视解,同时用递归与迭代法分别去实现!

1,循环(loop),指的是在满足条件的情况下,重复执行同一段代码。比如,while语句。   循环则技能对应集合,列表,数组等,也能对执行代码进行操作。
2,迭代(iterate),指的是按照某种顺序逐个访问列表中的每一项。比如,for语句。    迭代只能对应集合,列表,数组等。不能对执行代码进行迭代。
3,遍历(traversal),指的是按照一定的规则访问树形结构中的每个节点,而且每个节点都只访问一次。   遍历同迭代一样,也不能对执行代码进行遍历。
4,递归(recursion),指的是一个函数不断调用自身的行为。比如,以编程方式输出著名的斐波纳契数列。
    (1),通俗的解释:递归就像往存钱罐里存钱,先往里边塞钱,2块,5块,10块这样的塞,叫入栈。取钱的时候,后塞进去的先取出来,这叫出栈。具体多少钱,要全部出栈才知道。  
    (2),递归分类:线性递归和尾递归。

递归法——《盗梦空间》

递归,就是在运行的过程中调用自己,每次旨在缩小问题规模。
构成递归需具备的条件:
1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。

迭代法——《明日边缘》

迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程。

迭代是自己执行很多次,每次旨在更接近目标。

1.欧几里德算法,典型的迭代法

最经典的迭代算法,用于计算两个整数a,b的最大公约数。

假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:

以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。

java代码实现算法: 

package com.azdebugit.suanfa.test.diedai;

public class ZuiDaGongYue {
    public static int gcd(int a, int b) {

        if (a <= 0 || b <= 0) {//预防错误
            return 0;
        }
        int temp;
        if (a < b) { //交换a,b保证a大于b
            temp = a;
            a = b;
            b = a;
        }
        //迭代计算
        while (b > 0) {  //边界条件
            temp = a % b;
            a = b;
            b = temp;
        }
        return a;//最大公约数
    }

    public static void main(String[] args) {
        System.out.println(gcd(128,28));
    }
}

欧几里得算法应用

RSA是第一个也是使用的最广泛的公钥加密算法,在1978年由R.Rivest、AdiShamir和Adleman三人发明,并以他们的名字命名。RSA算法的安全性基于大数因子分解的困难性,下面介绍一下它的基本原理:

 2.斐波那契数列

斐波纳契数列,又称黄金分割数列。

大学计算机课程中算法讲解中一个经典的数列计算。可以通过递归和非递归实现。
代码递归实现:

package com.azdebugit.suanfa.test.digui;

import org.springframework.util.StopWatch;

public class FiboTest {
    public static int fib(int n) {
        //边界判断
        if (n < 1) {
            return 0;
        }
        if (n == 1 || n == 2) {
            return 1;
        }

        return fib(n - 1) + fib(n - 2);
    }

//    代码非递归实现:

    public static int fib1(int n) {
        //边界判断
        if (n < 1) {
            return 0;
        }
        if (n == 1 || n == 2) {
            return 1;
        }
        int f1 = 1, f2 = 1, fn = 0;
        int i;
        for (i = 3; i <= n; i++) {//迭代计算
            fn = f1 + f2;
            f1 = f2;
            f2 = fn;
        }
        return fn;
    }

    public static void main(String[] args) {
        StopWatch s1 = new StopWatch();
        System.out.print("--递归实现--"+fib(50)+"----");
        System.out.println(s1.getTotalTimeMillis());
        StopWatch s2 = new StopWatch();
        System.out.print("--非递归实现--"+fib1(50)+"----");
        System.out.println(s2.getTotalTimeMillis());
    }
}

   3.牛顿迭代法

牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程f(x) = 0的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成超线性收敛。

该方法广泛用于计算机编程中。牛顿迭代关系式 

 

代码实现:

public class NewtonIterator {

    public static void main(String[] args) {
        double x = 10,precision = 0.000000001;
        int maxcyc = 100;
        NewtonIterator newtonIterator = new NewtonIterator();
        if(newtonIterator.newton(x, precision, maxcyc) == 1){
            System.out.println("该值附近的根为" + result + " 迭代次数 : " + num);
        }else{
            System.out.println("迭代失败!");
        }
    }

    private static double result;
    private static int num;

    public double func(double x){ //函数
        return x*x*x*x - 3*x*x*x + 1.5*x*x - 4.0;
    }

    public double func1(double x){//导数
        return 4*x*x*x - 9*x*x + 3*x;
    }

    public int newton(double x, double precision,int maxcyc){//迭代次数

        double x1,x0;
        int k;
        x0 = x;

        for(k = 0; k < maxcyc; k++){
            if (func1(x0) == 0.0) {
                System.out.println("迭代过程中导数为0!");
                return 0;
            }

            x1 = x0 - func(x0) / func1(x0);  //牛顿迭代计算关系式,x1是是曲线过点(x0,f(x0))做切线,相交于x轴上的横坐标
            if (Math.abs(x1-x0) < precision || Math.abs(func(x1)) < precision) {//精度判断,达到精度就结束迭代
                result = x1;
                num = k + 1;
                return 1;
            }else{
                x0 = x1;
            }
        }

        System.out.println("迭代次数超过预期!");
        return 0;
    }
}

计算结果

该值附近的根为2.648936536183 迭代次数 : 10

以上是关于采用递归与迭代法思想,分别用java编程去实现欧几里德,斐波那契,牛顿迭代法的主要内容,如果未能解决你的问题,请参考以下文章

归并排序

归并排序算法及其JS实现

图解排序算法之归并排序

图解排序算法之归并排序

图解排序算法之归并排序

图解排序算法之归并排序