国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - Java中的迭代和遞歸詳解

Java中的迭代和遞歸詳解

2020-07-07 12:40daisy JAVA教程

這篇文章主要給大家介紹了關于Java中的迭代和遞歸,文章顯示分別介紹了Java中的迭代和遞歸,而后又介紹了迭代和遞歸的區別以及數形遞歸的相關內容,文中介紹的很詳細,相信會對大家學習具有一定的參考借鑒價值,有需要的朋

前言

最近在看書的時候看到這一內容,感覺還是蠻有收獲的。迭代使用的是循環(for,while,do...wile)或者迭代器,當循環條件不滿足時退出。而遞歸,一般是函數遞歸,可以是自身調用自身,也可以是非直接調用,即方法A調用方法B,而方法B反過來調用方法A,遞歸退出的條件為if,else語句,當條件符合基的時候退出。

上面是迭代和遞歸的語法特性,他們在Java中有什么不同呢?下面通過這篇文章來詳細了解了解。

一、遞歸

提到迭代,不得不提一個數學表達式: n!=n*(n-1)*(n-2)*...*1

有很多方法來計算階乘。有一定數學基礎的人都知道n!=n*(n-1)!因此,代碼的實現可以直接寫成:

代碼一

?
1
2
3
4
5
6
7
int factorial (int n) {
 if (n == 1) {
  return 1;
 } else {
  return n*factorial(n-1);
 }
}

在執行以上代碼的時候,其實機器是要執行一系列乘法的: factorial(n) factorial(n-1) factorial(n-2) → … → factorial(1) 。所以,需要不斷的跟蹤(跟蹤上次計算的結果)并調用乘法進行計算(構建一個乘法鏈)。這類不斷調用自身的運算形式稱之為遞歸。遞歸可以進一步的分為線性遞歸和數形遞歸。信息量隨著算法的輸入呈線性增長的遞歸稱之為線性遞歸。計算n!(階乘)就是線性遞歸。因為隨著N的增大,計算所需的時間呈線性增長。另外一種信息量隨著輸入的增長而進行指數增長的稱之為樹形遞歸。

二、迭代

另外一種計算n!的方式是:先計算1乘以2,然后用其結果乘以3,再用的到的結果乘以4….一直乘到N。在程序實現時,可以定義一個計數器,每進行一次乘法,計數器都自增一次,直到計數器的值等于N截至。代碼如下:

代碼二

?
1
2
3
4
5
6
7
int factorial (int n) {
 int product = 1;
 for(int i=2; i<n; i++) {
  product *= i;
 }
 return product;
}

和代碼一相比,代碼二沒有構建一個乘法鏈。在進行每一步計算時,只需要知道當前結果(product)和i的值就可以了。這種計算形式稱之為迭代。迭代有這樣幾個條件:1、有一個有初始值的變量。2、一個說明變量值如何更新的規則。3、一個結束條件。(循環三要素:循環變量、循環體和循環終止條件)。和遞歸一樣。時間要求隨著輸入的增長呈線性的可以叫做線性迭代。

三、迭代 VS 遞歸

比較了兩個程序,我們可以發現,他們看起來幾乎相同,特別是其數學函數方面。在計算n!的時候,他們的計算步數都是和n的值成正比的。但是,如果我們站在程序的角度,考慮他們是如何運行的話,那么這兩個算法就有很大不同了。

(注:原文中關于其區別寫的有點扯,這里就不翻譯了,下面是筆者自己總結內容。)

首先分析遞歸,其實遞歸最大的有點就是把一個復雜的算法分解成若干相同的可重復的步驟。所以,使用遞歸實現一個計算邏輯往往只需要很短的代碼就能解決,并且這樣的代碼也比較容易理解。但是,遞歸就意味著大量的函數調用。函數調用的局部狀態之所以用棧來記錄的。所以,這樣就可能浪費大量的空間,如果遞歸太深的話還有可能導致堆棧溢出。

接下來分析迭代。其實,遞歸都可以用迭代來代替。但是相對于遞歸的簡單易懂,迭代就比較生硬難懂了。尤其是遇到一個比較復雜的場景的時候。但是,代碼的難以理解帶來的有點也比較明顯。迭代的效率比遞歸要高,并且在空間消耗上也比較小。

      遞歸中一定有迭代,但是迭代中不一定有遞歸,大部分可以相互轉換。

      能用迭代的不要用遞歸,遞歸調用函數不僅浪費空間,如果遞歸太深的話還容易造成堆棧的溢出。

四、數形遞歸

前面介紹過,樹遞歸隨輸入的增長的信息量呈指數級增長。比較典型的就是斐波那契數列:

Java中的迭代和遞歸詳解

用文字描述就是斐波那契數列中前兩個數字的和等于第三個數字:0,1,1,2,3,5,8,13,21……

遞歸實現代碼如下:

?
1
2
3
4
5
6
7
8
9
int fib (int n) {
 if (n == 0) {
  return 0;
 } else if (n == 1) {
  return 1;
 } else {
  return fib(n-1) + fib(n-2);
 }
}

計算過程中,為了計算fib(5) ,程序要先計算fib(4) fib(3) ,要想計算fib(4) ,程序同樣需要先計算 fib(3) fib(2) 。在這個過程中計算了兩次fib(3)。

從上面分析的計算過程可以得出一個結論:使用遞歸實現斐波那契數列存在冗余計算。

就像上面提到的,可以用遞歸的算法一般都能用迭代實現,斐波那契數列的計算也一樣。

?
1
2
3
4
5
6
7
8
9
10
int fib (int n) {
 int fib = 0;
 int a = 1;
 for(int i=0; i<n; i++) {
  int temp = fib;
  fib = fib + a;
  a = temp;
 }
 return fib;
}

雖然使用遞歸的方式會有冗余計算,可以用迭代來代替。但是這并不表明遞歸可以完全被取代。因為遞歸有更好的可讀性。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者使用Java能有所幫助,如果有疑問大家可以留言交流。

原文鏈接:http://www.hollischuang.com/archives/1298

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品99国产精品日本 | 日韩国产欧美一区 | 亚洲成人福利 | 黄色一级免费大片 | 成人国产免费视频 | 亚洲精品综合 | 国产成人精品免费 | 激情久久婷婷 | 欧美视频一区二区三区 | 免费在线黄色电影 | 日韩精品久久久 | 欧美日韩第一区 | 国产第一亚洲 | 日韩中文字幕一区二区 | 久久久久亚洲 | 亚洲视频 欧美视频 | 日韩欧美精品一区 | 色综合社区 | 国内成人精品2018免费看 | 欧美午夜精品久久久 | 91在线免费观看 | 香蕉福利视频 | 亚洲激情一区 | 成人免费xxxxx在线视频软件 | 免费自拍偷拍视频 | 日韩毛片 | 国内自拍视频在线观看 | 男女啪啪无遮挡 | 日韩三级 | 99re国产| 欧美一级毛片日韩一级 | 天天艹久久 | 欧美日本在线 | 可以免费看黄色的网站 | 麻豆精品国产91久久久久久 | 亚洲在线一区 | 性做久久| 久久av一区二区三区 | 黄在线免费观看 | 亚洲精品成人 | 日韩欧美专区 |