簡體   English   中英

遞歸不僅僅是一個函數本身

[英]More to Recursion than Just a Function Calling Itself

我所見過的有關遞歸函數的每本教科書都以階乘為例,這雖然很有幫助,但並不能完全說明問題。

出於編程目的,遞歸函數可以將某個函數作為其基本情況,可以在其主體中包含其他函數調用,還是可以在不同的遞歸級別上以不同的方式執行?

而且,如果它做這些事情中的任何一件,它是否仍然是一個“遞歸函數”或現在是其他東西?

遞歸函數的定義就是“調用自身的函數”。 因此,如果您有一個調用自身的函數,則它是一個遞歸函數。

其他任何事情都僅取決於您使用的語言的功能。

這是一個相當簡單的遞歸函數示例,該函數簡單地將集合中的所有值(表示為堆棧的數組)輸出到瀏覽器控制台,因為它使用.pop()方法將其從堆棧中彈出。

totalSize值在整個調用堆棧中不會改變,因此可以通過將當前堆棧大小除以原始大小來測量中途點。

要回答在遞歸中不同級別上行為是否不同的問題,答案是肯定的:

// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];

// recursive function that calls itself. It behaves slightly different at
 // the halfway point
function test(totalSize, col) {
    if(col == undefined || col.length == 0) {
        return 0;

     } else {
        if(col.length / totalSize < .5) {
            console.log("Past 1/2 way point!");
        }
        console.log("total = " + totalSize);
        console.log("col.pop() = " + col.pop());
        return test(totalSize, col);
    }
}

// make a call to the function with the total size and the collection
test(coll.length, coll);

此外,您還詢問是否可以調用其他函數,這也是可能的。 在下面的示例中,一個函數用於返回基本情況的結果,而一個函數則用於抽象中途行為:

// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];

// recursive function that calls itself. It behaves slightly different at
 // the halfway point
function test(totalSize, col) {
    if(col == undefined || col.length == 0) {
        return handleBaseCase(totalSize, col);

     } else {
        // handle if it's at 1/2 way point
        handleHalfwayPoint(totalSize, col);  

        console.log("tital = " + totalSize);
        console.log("col.pop() = " + col.pop());
        return test(totalSize, col);
    }
}

function handleHalfwayPoint(totalSize, collection) {
    if(collection.length / totalSize < .5) {
        console.log("Past 1/2 way point!");
    }
}

// instead of returning 0, return "Done" and also print to the log
function handleBaseCase(totalSize, collection) {
    console.info("Done!");
    return "Done!";
}

// make a call to the function with the total size and the collection
test(coll.length, coll);

盡管這些特定示例無法解決任何現實問題,但它演示了如何在另一個函數中調用一個函數的概念可以擴展為處理其他用例。 教科書中的示例僅旨在教您遞歸的基礎知識,並幫助您配備必要的工具,以解決將來遇到的更復雜的實際問題。

由於此功能語言是JavaScript,因此運行它們的障礙很低。 您可以通過在Chrome開發者控制台中運行代碼來嘗試這些示例,也可以在一個小的測試HTML文件中運行它們。 祝好運!

遞歸函數是在其主體中調用自身一次或多次的函數。 函數也可以是相互遞歸的,其中一個函數是根據第二個定義的,反之亦然。

我已經進行了20多年的編程,無需遞歸。 使我真正了解遞歸調用的必要性和妙處的是Scheme語言和諸如“ The Little Schemer”之類的書。

並非所有的編程語言都支持同一級別的遞歸。 計划是做得很好的人之一。 Python要少得多。 因此,如果您想深入研究遞歸,請檢查您的編程語言的功能。

正如其他答案所言,遞歸函數是一個調用自身的函數。 有兩種類型的解釋在這里

  1. 直接遞歸:函數在其中調用自身。
  2. 間接遞歸:當一個函數不是由其本身而是由其調用的另一個函數(直接或間接)調用時。

我在您的問題中看到了數學標記。 遞歸與數學歸納有關。 如果您證明它可以解決基本情況,然后證明如果無數個語句序列中的任何一個語句為真,那么下一個語句也是如此,那么您將證明它可以解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM