递归函数到非递归函数?

时间:2013-11-11 15:29:14

标签: recursion groovy

我有以下递归Grails函数:

private boolean isCyclic(TreeNode node) {
    boolean cyclic = false
    def myParents = this.parents

    // if there are parents of this node
    if (myParents.size() != 0) {

        // if the new node is in the parents set of this node
        if (myParents.contains(node)) {
            cyclic = true
            return cyclic
        }
        else {
            // go into each parent of this node and test if new node is contained in their parents
            myParents.each { parent ->
                log.debug "go to parent: "+parent.name
                if (cyclic) {
                    return cyclic
                }
                cyclic = parent.isCyclic(node)
            }
        }
    }

    return cyclic
}

如何将此函数转换为非递归函数?

3 个答案:

答案 0 :(得分:2)

认为上面的代码是contains方法,而不是循环检查......

然而,这是一个包含方法和迭代风格的循环检查的快速示例...手指交叉它们是正确的

def contains( TreeNode node ) {
    // if this node is the one we're looking for, return true
    if( node == this ) {
        return true
    }
    // A queue of nodes to work on
    def parentQueue = this.parents as Queue

    // A set of nodes we've seen (to avoid loops)
    def seen = [ this ] as Set

    // While we have nodes to look for
    while( parentQueue ) {
        // get the next node
        def next = parentQueue.pop()

        // Check if it's the one we're looking for
        if( next == node ) return true

        // And if not, add it's parents to the queue
        // assuming we've not seen it before
        if( !seen.contains( next ) ) {
            next.parents.each { parentQueue.offer( it ) }
        }
    }
    // Not found
    return false
}

def isCyclic() {
    // A queue of nodes to work on
    def parentQueue = this.parents as Queue

    // A set of nodes we've seen (to detect loops)
    def seen = [ this ] as Set

    // While we have nodes to look for
    while( parentQueue ) {
        // Look at the next element in the queue
        def next = parentQueue.pop()

        // If we've seen it before, it's cyclic
        if( seen.contains( next ) ) return true

        // Otherwise, record we've seen this node
        seen << next

        // And add its parents tothe queue
        next.parents.each { parentQueue.offer( it ) }
    }
    // All done, not cyclic
    return false
}

答案 1 :(得分:0)

基本上要将递归函数转换为迭代函数,您应该注意哪个是案例库(这种情况是递归函数的停止案例),将所有功能放入循环并使用该基本情况作为使用循环的退出条件

也许我没有很好地解释它,但每个递归函数都有一个迭代函数。

答案 2 :(得分:0)

Tom Moertel在他的博客上为此问题编写了解决方案。 他清楚地解释了递归函数到迭代(link)的转换。

在我需要的时候,我已经用他的方法来改变自己的功能,我确信这是正确的。

我希望有所帮助。