递归如何在排列中起作用?

时间:2015-10-03 21:25:54

标签: algorithm recursion

我正在研究编写here的排列程序。代码如下所示:

public static void main(String[] args) {
    permutation("", "CAT");
}

private static void permutation(String prefix, String str) {
    int n = str.length();
    if (n == 0) {
        System.out.println(prefix);
    } else {
        for (int i = 0; i < n; i++) {
            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1));
        }
    }
}

对于单词CAT,我得到以下输出:
CAT
CTA
ACT
ATC
TCA
TAC

我可以追溯递归的步骤,并了解它如何工作以获得CAT和CTA,但我不知道它是如何继续下去的。在n == 0(这是基本情况)之后,一切都应该停止(这将在我们获得CTA之后发生)。

其他来源:
我阅读了here的解释,但我仍然无法理解它是如何继续下去的。我觉得我得到了递归的概念。我可以盲目地使用它,但我想了解它是如何在这里工作的。

还有另一个版本的排列递归here,但这是使用回溯,我理解那个更好一点。这是我不理解的尾递归法。

问题:
有人可以解释递归是如何工作的,以便我们在上面的例子中通过CTA?这不是家庭作业。我只是在研究不同的程序并通过一些技能构建者进行工作。

谢谢!

3 个答案:

答案 0 :(得分:1)

让我们看一下第一个电话产生的内容:

("" + str.charAt(0), str.substring(0, 0) + str.substring(0 + 1))
p("C", "AT")

("" + str.charAt(1), str.substring(0,1) + str.substring(1 + 1))
p("A", "CT")

("" + str.charAt(2), str.substring(0, 2) + str.substring(2 + 1))
p("T", "CA")

每次调用都会提取str的每个字母,并将其添加到当前前缀中。第一个调用将原始字符串的每个字母作为排列的开头。然后,对于每个这样的排列,算法提取剩余后缀的每个字母并将其添加到累积前缀,以便探索所有可能性:

C AT
    CA T
    CT A
        "CAT"
        "CTA"

A CT
    AC T
    AT C
        "ACT"
        "ATC"

T CA
    TC A
    TA C
         "TCA"
         "TAC"

答案 1 :(得分:0)

记住每个递归调用的状态(每个局部变量和参数的值)。在CAT返回后,只有一个呼叫结束,其他呼叫在他们离开的地方继续。

将每个递归调用视为对一个全新函数的调用,该函数碰巧执行相同的操作。

这是你的函数执行的方式。如果您还编写了每个局部变量的值(在您的情况下,它只是i和参数),这可能会有所帮助。我刚写了什么叫什么。

p("", "CAT") -> p("C", "AT") -> p("CA", "T") -> p("CAT", "") -> CAT and return
                                             -> return
                             -> p("CT", "A") -> p("CTA", "") -> CTA and return
                                             -> return
                             -> return
             -> p("A", "CT") -> ...

答案 2 :(得分:0)

要了解递归,我们必须从“阶乘递归”开始