Recursion 我想这已经是一个很好的例子了。但如果不是,我该怎么做呢?

Recursion 我想这已经是一个很好的例子了。但如果不是,我该怎么做呢?,recursion,groovy,tail-recursion,Recursion,Groovy,Tail Recursion,我同意,这不是问题的最佳标题。但我想不出别的办法。对不起 在Groovy中编写一个简单的单链表代码,我想添加一个方法,该方法接收两个列表,并将右列表追加到左列表。这就是我想要的 private static class Node { Node next = null def head @TailRecursive Node append(Node left = this, Node right) { if (!right) return left

我同意,这不是问题的最佳标题。但我想不出别的办法。对不起

在Groovy中编写一个简单的单链表代码,我想添加一个方法,该方法接收两个列表,并将右列表追加到左列表。这就是我想要的

private static class Node {
    Node next = null
    def head

    @TailRecursive
    Node append(Node left = this, Node right) {
        if (!right) return left
        if (!left) return right

        if (!left.next) left.next = right
        else left.next = append(left.next, right)

        return left
    }
}
但我错了

LinkedList.groovy: 23: Recursive call could not be transformed by @TailRecursive. Maybe it's not a tail call.
 @ line 23, column 30.
               else head.next = append(head.next, tail)

是不是因为最后的return语句才不是尾部递归的?我如何解决这个问题?

下面这样的东西就足够了

import groovy.transform.TailRecursive

@TailRecursive
LinkedList mergeLinkedList(LinkedList left = [], LinkedList right = []) {
    if ( !left ) {
        right
    } else if ( !right ) {
        left
    } else {
        left.add( right.head() )
        mergeLinkedList( left, right.tail() ) 
    }
}

def left = (1..100) as LinkedList, right = (200..500) as LinkedList

assert mergeLinkedList( left, right ) == ((1..100) + (200..500)) as LinkedList
根据给出的提示,下面是尾部递归实现。它应该和我在问题中发布的非尾部递归一样有效

@TailRecursive
Node append(Node prevTail = this, Node tail = this?.next, Node right) {
    if (!right) return left
    if (!prevTail) return right

    if (!tail) prevTail.next = right
    else return append(tail, tail?.next, right)
}

尾部递归函数必须立即返回递归大小写的值——否则不能使用它。好的,我现在就知道了。但是,如何使这个函数尾部递归。我知道这是可以做到的,因为我在一本关于Scala的书中读到过。但是,如何在Groovy中实现它呢?请考虑定义为<代码>附加函数(PrimeT尾,Tro尾,TraceOrthor)(这可以是辅助函数),那么您是否已经尝试过该定义?它将被递归地称为
append(left,left.next,right)
,这样工作就可以“向下推”。或者,更干净(但它完全抛出了当前代码),只需创建一个
lastnode
函数,从左尾迭代到尾。然后修改最后一个节点并继续。@user2864740抱歉,我有点忙,无法回到问题上来。谢谢你的建议。成功了。然而,我不理解第二种方法。你能再详细描述一下吗?如果我不想为内置的
LinkedList
类编写,而是为我在问题中遇到的类编写呢?在每个递归调用中将元素添加到
left
的末尾将处理
n
n+1
n+m
最后(假设
左侧有
n
元素,右侧有
m
)。就我所见,这应该会导致
O(n+m^2)
复杂性。我的实现虽然不是尾部递归的,但如果我没有错的话,只需要
O(n)
。有没有一种方法可以使用尾部递归实现同样的复杂性?