Java遞迴(recursion),java遞迴recursion

來源:互聯網
上載者:User

Java遞迴(recursion),java遞迴recursion

人分兩種:男人和女人;演算法分兩種:遞迴的和迭代/迴圈的;遞迴是指用自己的較簡單的情形定義自己

在數學和電腦科學中,遞迴是一種思路和策略,可以用於術語的定義(什麼是運算式)問題的描述問題求解。用於問題求解的遞迴稱為遞迴法。

有一個故事。物理學家計算10!時會說,“看,它等於1*2*~*10,即3628800”;數學家則說:“哦,10的階乘,它等於10乘以9!”。

遞迴演算法“輕率地”認為自己的較簡單的情形是已知的。既然fact(n-1)是已知的,因而fact(n) 可求。這樣“輕率”對理解遞迴概念至關重要。遞迴法不直接解決問題,而是將問題變成一個趨向遞迴出口的問題。使用遞迴方法需要存在一個基準情形,以避免無限迴圈(狗追自己的尾巴)。


package algorithm.recursion;public class RecursionDemo{        /**     * 遞迴求Fibonacci級數的第n個元素,n基於1的自然數。     */    public static int fibonacc(int n){        if(n<=1) return n;        else return fibonacc(n-1)+fibonacc(n-2);    }        /**     * 迭代求Fibonacci級數的第n個元素,n基於1的自然數。     */    public static int fibonacc1(int n){        int first , second ,result ;        first =second=result= 1;        for(int i=3;i<=n ;i++){            result = first + second;            first = second;            second =result;        }        return result;    }    }
大多數情況下,迭代法和遞迴法能夠相互轉化。

使用遞迴法有2條實踐準則:

1、設計優先。在任何情況下都可以採用遞迴法,簡潔而清晰的程式設計優先。某些問題,例如那些需要後退的問題(如找出迷宮的出路、對樹的一些操作),如果不採用遞迴則很難解決。

2、 效率平衡。如果遞迴調用中出現重複性工作,改用迴圈。對於一般的數值計算,遞迴法通常不合適。

Java遞迴方法是通過方法調用棧實現的。在BlueJ中設定斷點運行factorial (5),將顯示方法調用情況。它僅僅“輕率地認為”factorial (4)已知,依此類推。到factorial (5),目前沒有進行任一乘法計算。方法調用棧中有6個棧幀,頂層將計算factorial (0)。遞迴的方法的兩個階段是遞推和迴歸

例如使用遞迴式sum(n) =n + sum(n-1),yqj2065看見過一個趣題。

    static long sum1(long a) {        return (a == 1)? 1:(a + sum1(a - 1));    }    static long sum2(long a) {        return (a == 1)? 1:(sum2(a - 1) + a);    }
兩者有區別嗎?【註:在Java7時sum1(6000)StackOverflowError,Java8到大約13000才溢出。 原因不明。】

漢諾塔

漢諾塔問題(Hanoi Tower problem):有三根杆子A、B、C,A杆上串有上小下大若干碟子。每次移動一塊碟子,在確保小碟子只能疊在大碟子上面的條件下,利用B過渡,請把所有碟子從A杆移到C杆上。

對於具有遞迴思維的人,再多的碟子,也不過是兩部分:上面的n-1個碟子被看成粘在一起的小碟子,而下面是一個大碟子。漢諾塔問題的遞迴演算法:

結束條件: A杆上只有一個碟子,將它移到C。

遞迴式:

1、將上面的n-1個碟子從出發地A移到中轉站B;

2、將第n個碟子移到目的地C;

3、將n-1個碟子從中轉站B移到目的地C。

package algorithm.recursion;public class HanoiTower{    private static int step= 0;       /**漢諾塔的遞迴示範。     * @param from  碟子的出發地     * @param temp  碟子的中轉站     * @param to   碟子的到達地     * @param n  要移動的碟子個數     */    static void  hanoi(char from, char temp, char to, int n){         if (n == 1) {           step++;           System.out.println("第"+step+ "步: "+ from+"→"+ to);        }else {            //將n-1個碟子移到中轉站,故目前的到達地是temp。            hanoi(from, to,temp,n-1);            //第n個碟子移到到達地            step++;            System.out.println("第"+step+ "步: "+ from+"→"+ to);            //將n-1個碟子移到到達地。            hanoi(temp,from,to,n-1);        }    }}
hanoi(‘A’, ‘B’, ‘C’, 3)的輸出:

第1步: A→C
第2步: A→B
第3步: C→B
第4步: A→C
第5步: B→A
第6步: B→C
第7步: A→C

漢諾塔問題的迭代演算法比較複雜,程式碼程式庫中有參考實現。

練習:

1.Given a non-negative int n, return the sum of its digits recursively (no loops). Note that mod (%) by 10 yields the rightmost digit (126 % 10 is 6), while divide (/) by 10 removes the rightmost digit (126 / 10 is 12). 

sumDigits(126) → 9
sumDigits(49) → 13
sumDigits(12) → 3

類似的: 遞迴求一個非負int包含的5的個數。

2.小朋友排排坐,單號伸出2手指,雙號伸出3手指,遞迴求n個小朋友時手指的總數。

sum(0) → 0
sum(1) → 2
sum(2) → 5



Java 遞迴 Recursion

method1函數遞迴調用自己,當遇到普通檔案ff.txt時,會執行“return”語句返回;返回只是返回到上一級method1()調用,並不會退出整個程式。你之所以認為會停下來,是因為你對函數遞迴調用的概念還沒理解。
 
java解答一題recursion遞迴的問題

public static int divide(int a, int b) {int result = 0;while (a >= b) {result++;a = a - b;}return result; }public static final void main(String[] args) {System.out.println(divide(60, 12));System.out.println(divide(27, 8));}
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.