“嗨,Amigo。今天 Bilaabo 將向您介紹遞歸。”
如您所知,在 Java 中,一些方法會調用其他方法。此外,當一個方法被調用時,特定的參數被傳遞給它,但是方法的局部變量在它運行時採用特定的值。
“嗯。”
“正如你所知,不同方法的內部變量是相互獨立的。”
“嗯。”
“所以想像一下方法調用自身的情況。這稱為遞歸。例如:”
public static void main(String[] args)
{
countDown(10);
}
public static void countDown(int x)
{
if (x <= 0)
System.out.println("Boom!");
else
{
System.out.println(x);
countDown(x - 1);
}
}
10
9
8
7
6
5
4
3
2
1
Boom!
“我可以看到該方法在代碼中調用了自身,但老實說我不明白髮生了什麼。”
“好吧,當調用不同的方法時會發生同樣的事情。”
“不,我問的是變量會發生什麼?它們的值會怎樣?我們如何退出方法?還是一次性退出所有內容?”
“天哪。一切都簡單多了。想像一下,調用自身的方法被乘以了很多次。那麼我們就會遇到類似的情況:”
遞歸方法調用 | 到底發生了什麼 |
---|---|
|
|
屏幕輸出: | 屏幕輸出: |
---|---|
|
|
“換句話說,每次調用一個方法(甚至調用它自己)時,都會創建新變量來存儲該方法的數據。沒有共享變量。”
“每次調用時,都會在內存中創建具有新值的方法參數的另一個副本。當我們返回到舊方法時,它的變量會在那裡使用。換句話說,在遞歸期間我們實際上調用了另一個方法,但是使用和我們的代碼一樣! ”
“我明白了。退出這種方法是如何工作的?也許是一個例子?”
“好的。一個例子勝過一千個字。”這是你的例子:
遞歸方法調用 | 遞歸方法調用 |
---|---|
|
|
屏幕輸出: | 屏幕輸出: |
---|---|
|
|
“好的。我想我明白了。為什麼我們需要遞歸?”
“有很多很多任務可以分成與原始任務相同的單獨子任務。例如,您需要遍歷 XML 樹的所有元素。每個元素可以有幾個子元素,它們有自己的子元素自己的子元素。”
“或者你需要顯示一個目錄及其所有子目錄中的文件列表。所以你寫了一個方法來顯示當前目錄的文件。然後要獲取所有子目錄的文件,你調用你的方法使用不同的論點:一個子目錄。”
“例如:”
public static void main(String[] args)
{
printAllFiles(new File("c:/windows/"));
}
public static void printAllFiles(File dir)
{
for (File file : dir.listFiles())
{
if (file.isDirectory())
printAllFiles(file);
else
System.out.println(file.getAbsolutePath());
}
}
“第 8 行——我們獲取 dir 目錄中所有文件(和目錄)的列表。”
“第 10-11 行——如果文件實際上是一個目錄,那麼我們再次調用printAllFiles,但這次有另一個參數:子目錄。”
“第 13 行——我們顯示當前文件的名稱。”
“好的。我想我明白了。謝謝你,Bilaabo。”
GO TO FULL VERSION