Java 为泛型递归程序生成递归树的程序

Java 为泛型递归程序生成递归树的程序,java,c++,recursion,visualization,Java,C++,Recursion,Visualization,通常在解决递归或动态规划问题时,我会画一棵递归树来帮助简化问题。然而,对于一些复杂的问题,我可以找到答案,但不知道如何绘制树 到目前为止,我所尝试的是打印出调用函数及其参数,这在一些示例中证明是有用的。然而,我在这个答案中看到了mathematica生成的fibonacci5树: 我想知道我是否能在主流的高级语言中生成相同的树,比如Python、java或C++?树可以只将节点作为函数名和参数,如图中所示 请看一看和 以下是一个例子: long long fib(int n) { if

通常在解决递归或动态规划问题时,我会画一棵递归树来帮助简化问题。然而,对于一些复杂的问题,我可以找到答案,但不知道如何绘制树

到目前为止,我所尝试的是打印出调用函数及其参数,这在一些示例中证明是有用的。然而,我在这个答案中看到了mathematica生成的fibonacci5树:

我想知道我是否能在主流的高级语言中生成相同的树,比如Python、java或C++?树可以只将节点作为函数名和参数,如图中所示

请看一看和

以下是一个例子:

long long fib(int n)
{
    if (n <= 1) return 1;
    std::cout << "fib" << n << " -> fib" << n-2 << '\n';
    std::cout << "fib" << n << " -> fib" << n-1 << '\n';
    return fib(n-2) + fib(n-1);
}

int main()
{
    std::cout << "digraph {\n";
    fib(5);
    std::cout << "}\n";
}
制作:

这比请求的映像更紧凑,其中具有相同值的重复调用由一个节点表示,如果从fibu到fibv有N个调用,则节点u、v之间有N条边

要获得树,必须为每个调用维护唯一的ID。以下是一个例子:

static unsigned id = 0;
long long fib(int n)
{
    auto call_id = id++;
    std::cout << "fib" << call_id << " [label=\"fib(" << n << ")\"]\n";
    if (n <= 1) return 1;
    std::cout << "fib" << call_id << " -> fib" << id << '\n';
    auto fib_n_minus_2 = fib(n-2);
    std::cout << "fib" << call_id << " -> fib" << id << '\n';
    auto fib_n_minus_1 = fib(n-1);
    return fib_n_minus_2 + fib_n_minus_1;
}

int main()
{
    std::cout << "digraph {\n";
    fib(5);
    std::cout << "}\n";
}
图为:

看一看和

以下是一个例子:

long long fib(int n)
{
    if (n <= 1) return 1;
    std::cout << "fib" << n << " -> fib" << n-2 << '\n';
    std::cout << "fib" << n << " -> fib" << n-1 << '\n';
    return fib(n-2) + fib(n-1);
}

int main()
{
    std::cout << "digraph {\n";
    fib(5);
    std::cout << "}\n";
}
制作:

这比请求的映像更紧凑,其中具有相同值的重复调用由一个节点表示,如果从fibu到fibv有N个调用,则节点u、v之间有N条边

要获得树,必须为每个调用维护唯一的ID。以下是一个例子:

static unsigned id = 0;
long long fib(int n)
{
    auto call_id = id++;
    std::cout << "fib" << call_id << " [label=\"fib(" << n << ")\"]\n";
    if (n <= 1) return 1;
    std::cout << "fib" << call_id << " -> fib" << id << '\n';
    auto fib_n_minus_2 = fib(n-2);
    std::cout << "fib" << call_id << " -> fib" << id << '\n';
    auto fib_n_minus_1 = fib(n-1);
    return fib_n_minus_2 + fib_n_minus_1;
}

int main()
{
    std::cout << "digraph {\n";
    fib(5);
    std::cout << "}\n";
}
图为:

我制作了一个简单的python包,名为,您可以通过pip安装该包,它可以帮助您轻松跟踪任意递归函数的函数调用,并通过简单地向函数添加一个装饰器将树保存为gif和png图像

让我们画递归斐波那契函数的树。 下面是递归代码:

def fib(n):
    if n <= 1:
        return n
    return fib(n=n - 1) + fib(n=n - 2)

def main():
    # Call function
    print(fib(n=6))

if __name__ == "__main__":
    main()
现在,让我们修改代码以绘制递归树。首先让我们画一个极简主义的例子

# Import Visualiser class from module visualiser
from visualiser.visualiser import Visualiser as vs

# Add decorator
@vs()
def fib(n):
    if n <= 1:
        return n
    return fib(n=n - 1) + fib(n=n-2)

def main():
    print(fib(n=6))
    vs.make_animation("fibonacci.gif", delay=2)

if __name__ == "__main__":
    main()
输出文件另存为fibonacci.gif和fibonacci.png。 以下是输出动画的外观: 还有递归树的最终图像:

我们还可以使用节点颜色和其他属性使其更好:

# Import Visualiser class from module visualiser
from visualiser.visualiser import Visualiser as vs

# Add decorator
@vs(node_properties_kwargs={"shape":"record", "color":"#f57542", "style":"filled", "fillcolor":"grey"})
def fib(n):
    if n <= 1:
        return n
    return fib(n=n - 1) + fib(n=n-2)

def main():
    print(fib(n=6))
    vs.make_animation("fibonacci.gif", delay=2)

if __name__ == "__main__":
    main()
以下是看起来更好的输出:

下面是递归树的最终图像:


查看更多示例我制作了一个简单的python包,名为,您可以通过pip安装该包,它可以帮助您轻松跟踪任意递归函数的函数调用,并通过简单地向函数添加装饰符将树另存为gif和png图像

让我们画递归斐波那契函数的树。 下面是递归代码:

def fib(n):
    if n <= 1:
        return n
    return fib(n=n - 1) + fib(n=n - 2)

def main():
    # Call function
    print(fib(n=6))

if __name__ == "__main__":
    main()
现在,让我们修改代码以绘制递归树。首先让我们画一个极简主义的例子

# Import Visualiser class from module visualiser
from visualiser.visualiser import Visualiser as vs

# Add decorator
@vs()
def fib(n):
    if n <= 1:
        return n
    return fib(n=n - 1) + fib(n=n-2)

def main():
    print(fib(n=6))
    vs.make_animation("fibonacci.gif", delay=2)

if __name__ == "__main__":
    main()
输出文件另存为fibonacci.gif和fibonacci.png。 以下是输出动画的外观: 还有递归树的最终图像:

我们还可以使用节点颜色和其他属性使其更好:

# Import Visualiser class from module visualiser
from visualiser.visualiser import Visualiser as vs

# Add decorator
@vs(node_properties_kwargs={"shape":"record", "color":"#f57542", "style":"filled", "fillcolor":"grey"})
def fib(n):
    if n <= 1:
        return n
    return fib(n=n - 1) + fib(n=n-2)

def main():
    print(fib(n=6))
    vs.make_animation("fibonacci.gif", delay=2)

if __name__ == "__main__":
    main()
以下是看起来更好的输出:

下面是递归树的最终图像:


查看更多的例子

你是在问如何编写一个生成树的程序,还是在问一个现有的这样的程序?@Petr如果有人有一个生成递归树的程序,那将非常好,我可以从那里阅读源代码并找出它。如果没有,那么从哪里开始的指针会很有帮助。你是在问如何编写一个生成树的程序,还是在问一个现有的这样一个程序?@Petr如果有人有一个生成递归树的程序,那会很好,我可以从那里读源代码并找出答案。如果不是的话,在哪里开始的指针将是有帮助的。