1. 程式人生 > >Java中的遞迴原理分析

Java中的遞迴原理分析

參加工作已經三四年了,再回頭來看這些很基礎的東西,覺得理解又深入了一層!

解釋:程式呼叫自身的程式設計技巧叫做遞迴。

程式呼叫自身的程式設計技巧稱為遞迴( recursion)。遞迴做為一種演算法在程式設計語言中廣泛應用。 一個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的程式碼量。遞迴的能力在於用有限的語句來定義物件的無限集合。

遞迴的三個條件:

  1. 邊界條件
  2. 遞迴前進段
  3. 遞迴返回段

當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。

下面通過兩個示例程式來說明:

  1. 使用Java程式碼求5的階乘。(5的階乘=5*4*3*2*1)

    package org.wxp.recursion;
    
    /**
     * 計算5的階乘(result = 5*4*3*2*1)
     * @author Champion.Wong
     * 
     *
     */
    public class Test01 {
    	public static void main(String[] args) {
    		System.out.println(f(5));
    	}
    	
    	public static int f(int n) {
    		if (1 == n) 
    			return 1;
    		else 
    			return n*f(n-1);
    	}
    }
    



    此題中,按照遞迴的三個條件來分析:
    (1)邊界條件:階乘,乘到最後一個數,即1的時候,返回1,程式執行到底;
    (2)遞迴前進段:當前的引數不等於1的時候,繼續呼叫自身;
    (3)遞迴返回段:從最大的數開始乘,如果當前引數是5,那麼就是5*4,即5*(5-1),即n*(n-1)

  2. 使用Java程式碼求數列:1,1,2,3,5,8......第40位的數
    package org.wxp.recursion;
    
    /**
     * 求數列:1,1,2,3,5,8......第40位的數
     * @author Champion.Wong
     * 
     */
    public class Test_02_Fibonacci {
    	public static void main(String[] args) {
    		System.out.println(f(6));
    	}
    	
    	public static int f(int n ) {
    		if (1== n || 2 == n) 
    			return 1;
    		else
    			return f(n-1) + f(n-2);
    	}
    }
    



    此題的突破口在:從第3位數開始,本位數是前兩位數的和。要計算第多少位的值,那麼就需要將位數作為引數傳進方法進行計算。
    (1)首先,當位數為1和2時,當前返回的值應該是1;
    (2)然後,當位數為3時,返回值應該=2=1+1;
                     當位數為4時,返回值=3=2+1;
                     當位數為5時,返回值=5=3+2;
                     當位數為6時,返回值=8=5+3;
                     ......
    (3)由(2)得知,大於等於3的情況下,當前位數(n)的數值=f(n-1)+f(n-2)




    心得:有些初學者可能認為遞迴即是自己呼叫自己,那豈不是死迴圈了。對,如果遞迴寫的不合理,那就是死迴圈了。但是如果寫的合理,加上“邊界條件”,程式執行到底的時候,會逐層返回。就像我們爬山一樣,我們繞著山路爬上一層又一層,如果沒有山頂,我們會一直往上爬。但如果到了山頂,就按照上山時候的步驟一層一層的往下爬。

相關推薦

Java原理分析

參加工作已經三四年了,再回頭來看這些很基礎的東西,覺得理解又深入了一層! 解釋:程式呼叫自身的程式設計技巧叫做遞迴。 程式呼叫自身的程式設計技巧稱為遞迴( recursion)。遞迴做為一種演算法在程式設計語言中廣泛應用。 一個過程或函式在其定義或說明中有直接或間接呼叫自

java演算法和漢諾塔

java中,一個方法呼叫它自身,被稱為方法遞迴。方法遞迴中包含了一種隱藏式的迴圈。它會重複執行某段程式碼,而且不需要迴圈語句控制。 例如有如下數學題。已知一個數列:f(0) =1 、f(1)=4、f(n+2) =2*f(n+1) + f(n),其中n是大於0的整數,求f(1

java實現函式入門級例子:用函式求一個數組的最大值

我們開始把陣列分為兩半,分別找出最大值,那麼這個最大值就是最後的最大值:同時我們左右兩邊繼續細分,停止條件就是細分到單個數值為止。 package chapter1; //使用遞迴求出一個數組中的最小值 public class FindMax { public sta

JAVA通過遍歷FTP的檔案以樹形結構顯示(JTree)

1、下載相應的jar包      commons-net-3.6.jar 2、具體程式碼如下 package org.ftp.conntion; import java.io.File; import javax.swing.JFrame; import javax

JAVA的集合原始碼分析一:ArrayList的內部實現原理

作為以java為語言開發的android開發者,集合幾乎天天都要打交道,無論是使用頻率最高的ArrayList還是HashSet,都頻繁的出現在平時的工作中。但是其中的原理之前卻一直沒深入探究,接下來記錄一下這次自己學習ArrayList原始碼的過程。 一.構造方法:

MySql、Oracle(通用方法)查詢生成檔案目錄樹(JAVA實現 過程不訪問資料庫,之前只訪問兩次 進行前資料準備)

查詢檔案樹 實體類 public class TradeInfoFile { ​ // 檔案編碼(子) private String fileCode; // 所屬檔案編碼(父) private String belongFileCode; // 交易

Java思想分析

先舉個例子:定義一個 sumByMax(int max)方法,求 1+…+max 的和 這個例子簡單的來講就是將1到max的所有整數都加起來,如果先不考慮用遞迴,那麼這就是一個個重複的累加步驟可以用迴圈來解決: public int sumByMax(int

C語言原理

最近在學資料結構的二叉樹,裡面的實現好多都是遞迴。博主大一上學期也沒有認真學遞迴,結果就好多不懂。今天特別請教了班上搞ACM的,再上網猜了一些資料才算初步弄懂遞迴的實現原理。遞迴的底層實現其實是棧,而棧是先進後出的(即先入棧的反而後出棧(類似水瓶中放物取物))下面是一段階乘遞

JavaArraylist源碼分析

如何 and 檢索 介紹 包括 com 這就是 pac 程序 前言:ArrayList作為我們常用的一個集合數據類型,我們在代碼中經常用它來裝載數據,可謂是和HashMap一樣常用的集合類型了。我們經常用它,那麽就有必須知道它的內部工作原理,比如它是如何添加進去數據的,它

支付寶app支付java後臺流程及原理分析

system 分析 req eterm 格式 prop 通過 false 由於 java版支付寶app支付流程及原理分析   本實例是基於springmvc框架編寫 一、流程步驟 1.執行流程 當手機端app(就是你公司開發的a

javaJVM的原理【轉】

ext eas 很大的 .class trap sub jdk與jre libraries use 一、java虛擬機的生命周期:   Java虛擬機的生命周期 一個運行中的Java虛擬機有著一個清晰的任務:執行Java程序。程序開始執行時他才運行,程序結束時他就停止。你

Java並發AQS原理分析(一)

jpg 子類 ole success ces || pro 同步 無法 我們說的AQS就是AbstractQueuedSynchronizer,他在java.util.concurrent.locks包下,這個類是Java並發的一個核心類。第一次知道有這個類是在看可重入鎖R

Java原子類實現原理分析

upd hat 16px 檢查 () 過程 jvm api 處理 並發包中的原子類可以解決類似num++這樣的復合類操作的原子性問題,相比鎖機制,使用原子類更精巧輕量,性能開銷更小,下面就一起來分析下原子類的實現機理。 悲觀的解決方案(阻塞同步)   我們知道,num++看

JavaInt轉byte分析

span 進行 二進制表示 size 二進制 light bsp 變量 byte[]   針對聲明變量 int i = 3,j = 8;    int占4個字節,i = 3 在Java二進制表示:      00000000 00000000 00000000 000000

java註解的原理和實現機制

                                          &

呼叫分析-最大自序列求和問題

昨天開始看《資料結構與演算法分析-java語言描述》這本書,在第二章舉例了一個演算法問題“最大子序列和問題”,在第三種遞迴方法,由於開始並沒有很好理解,遞迴呼叫在演算法中有很重要,用了最簡單一個例子來加深理解!(當然這種方法在這四種演算法中不是最優的)。 先給出原始碼: package

java篩選法求N以內的孿生質數(孿生素數)--附氣泡排序和插入排序練習

本人最近讀完一本書《質數的孤獨》,裡面講到孿生質數,就想查一下孿生質數的分佈情況。其中主要用到了計算質數(素數)的方法,搜了一下,排名前幾的都是用for迴圈來做的,感覺略微麻煩了一些,在比較一些還是覺得用遞迴篩選法來解決這個問題。 新建List<Integer>,然後從第0位開始,如

Python 漢諾塔原理

# -*- coding: utf-8 -*- # 遞迴的重點在於放棄,放棄理解和跟蹤遞迴全程的企圖,只理解遞迴兩層之間的交接,以及遞迴的終結條件 def move(n, start, mid, end): # n:盤子,start起始區,mid中轉區,end終點區 if n == 1:

Java 通過求解漢諾塔問題 原始碼 經典問題講解

漢諾塔問題描述:有三根柱子 A、B、C ,在A從下向上按照從大到小的順序放著64個圓盤,以B為中介,把盤子全部移動到C上。移動過程中,要求任意盤子的下面要麼沒有盤子,要麼只能有比它大的盤子。 分析:為了將N個盤子從A移動到C,需要先把第N個盤子上面的N-1個盤子移動到B上,這樣才能將第

java練習(1000的階乘尾部零的個數)

public class Test7 { public static void main(String[] args) { System.out.println(fun(1000)); } public static int fun(int num) { if(num&g