当前位置: 首页 > 知识库问答 >
问题:

如何在python上显示斐波那契递归树

於宏大
2023-03-14

这是我目前的代码:

from loguru import logger

def fibonacci(n, s="% s"):
    """
    Using recursive method
    """
    # logger.debug(f"Finding {n}th Fibonacci number")
    logger.debug(s % ("fib(%d)" % (n)))

    a = 0
    b = 1

    if n <= 0:
        return a
    elif n in (1, 2):
        return b
    else:
        return fibonacci(n - 1,  s % ("fib(%d) + %%s" % (n - 1))) + fibonacci(n - 2, s % ("fib(%d) + %%s" % (n - 2)))

我的目标是在日志中显示递归树,例如<code>fibonacci(5)</code>:

fib(5)
fib(4) + fib(3)
(fib(3) + fib(2)) + (fib(2) + fib(1))
and so on...

这可能吗?当前代码没有产生预期的输出。

电流输出:

fib(5)
fib(4) + fib(4)
fib(4) + fib(3) + fib(3)
fib(4) + fib(3) + fib(2) + fib(2)
fib(4) + fib(3) + fib(1) + fib(1)
fib(4) + fib(2) + fib(2)
fib(3) + fib(3)
fib(3) + fib(2) + fib(2)
fib(3) + fib(1) + fib(1)

理念:

共有2个答案

臧正平
2023-03-14

一种方法是,递归中的每个调用都可以将自身“报告”到其在树记录中的位置。然后我们可以逐级迭代。像这样:

def f(n):
  t = ["None"] * (2**(n-1) + 1)
 
  def g(n, i):
    l = "(" if i & 1 else ""
    r = ")" if not (i & 1) else ""
    t[i] = "%sfib(%s)%s" % (l, n, r)
 
    if n > 1:
      g(n-1, 2*i+1)
      g(n-2, 2*i+2)
 
  g(n, 0)
 
  print(t[0][0:-1])
  i = 1
  while 2**i-1 < len(t):
    print(" + ".join(t[2**i-1:2**(i+1)-1]))
    i += 1

输出:

f(5)

"""
fib(5)
(fib(4) + fib(3))
(fib(3) + fib(2)) + (fib(2) + fib(1))
(fib(2) + fib(1)) + (fib(1) + fib(0)) + (fib(1) + fib(0)) + None + None
(fib(1) + fib(0))
"""
权承
2023-03-14

您可以定义一个类来保存二叉树节点,并将树构建为递归fibonacci函数的结果:

class BNode:
    def __init__(self,value,left=None,right=None):
        self.value = value
        self.left  = left
        self.right = right
        
    def print(self):
        printBTree(self,nodeInfo=lambda n:(str(n.value),n.left,n.right))

from functools import lru_cache

@lru_cache()                   # optimize object count
def fiboTree(n):               # (n is an index, not a count)
    if n<2: return BNode(n)
    a,b = fiboTree(n-2),fiboTree(n-1)
    return BNode(a.value+b.value,a,b)

输出:

fiboTree(7).print()

                       13
          ____________/  \____________
         5                            8
   _____/ \____               _______/ \______
  2            3             3                5
 / \        __/ \_        __/ \_        _____/ \____
1   1      1      2      1      2      2            3
   / \    / \    / \    / \    / \    / \        __/ \_
  0   1  0   1  1   1  0   1  1   1  1   1      1      2
                   / \           / \    / \    / \    / \
                  0   1         0   1  0   1  0   1  1   1
                                                        / \
                                                       0   1

您可以在这里找到< code>printBTree函数

如果只需要说明调用层次结构,可以直接使用printBTree函数:

def fibo(n):
    n=int(n) # linking with strings to let zero come out as a node
    return (f"fibo({n})",[None,str(n-2)][n>1], [None,str(n-1)][n>1])


printBTree(5,fibo)

                      fibo(5)
            ____________/ \____________
     fibo(3)                           fibo(4)
       / \                          _____/ \____
fibo(1)   fibo(2)            fibo(2)            fibo(3)
            / \                / \                / \
     fibo(0)   fibo(1)  fibo(0)   fibo(1)  fibo(1)   fibo(2)
                                                       / \
                                                fibo(0)   fibo(1)

为了边打印边打印,我建议使用缩进来传达调用层次结构,否则重复添加将很难与调用方关联。

def fibo(n,indent=""):
    if n<2: return n
    print(indent[:-3] + "|_ "*bool(indent) 
          + f"fibo({n}) = fibo({n-2}) + fibo({n-1})")
    return fibo(n-2,indent+"|  ")+fibo(n-1,indent+"   ") 



fibo(7)

fibo(7) = fibo(5) + fibo(6)
|_ fibo(5) = fibo(3) + fibo(4)
|  |_ fibo(3) = fibo(1) + fibo(2)
|  |  |_ fibo(2) = fibo(0) + fibo(1)
|  |_ fibo(4) = fibo(2) + fibo(3)
|     |_ fibo(2) = fibo(0) + fibo(1)
|     |_ fibo(3) = fibo(1) + fibo(2)
|        |_ fibo(2) = fibo(0) + fibo(1)
|_ fibo(6) = fibo(4) + fibo(5)
   |_ fibo(4) = fibo(2) + fibo(3)
   |  |_ fibo(2) = fibo(0) + fibo(1)
   |  |_ fibo(3) = fibo(1) + fibo(2)
   |     |_ fibo(2) = fibo(0) + fibo(1)
   |_ fibo(5) = fibo(3) + fibo(4)
      |_ fibo(3) = fibo(1) + fibo(2)
      |  |_ fibo(2) = fibo(0) + fibo(1)
      |_ fibo(4) = fibo(2) + fibo(3)
         |_ fibo(2) = fibo(0) + fibo(1)
         |_ fibo(3) = fibo(1) + fibo(2)
            |_ fibo(2) = fibo(0) + fibo(1)

这可以说明记忆的好处/效果:

def fibo(n,indent="",memo=None):
    if n<2: return n
    if memo is None: memo = dict()
    print(indent[:-3] + "|_ "*bool(indent) + f"fibo({n})",end=" = ")
    if n in memo:
        print("taken from memo")
    else:
        print(f"fibo({n-2}) + fibo({n-1})")
        memo[n] = fibo(n-2,indent+"|  ",memo)+fibo(n-1,indent+"   ",memo)
    return memo[n]

fibo(7) = fibo(5) + fibo(6)
|_ fibo(5) = fibo(3) + fibo(4)
|  |_ fibo(3) = fibo(1) + fibo(2)
|  |  |_ fibo(2) = fibo(0) + fibo(1)
|  |_ fibo(4) = fibo(2) + fibo(3)
|     |_ fibo(2) = taken from memo
|     |_ fibo(3) = taken from memo
|_ fibo(6) = fibo(4) + fibo(5)
   |_ fibo(4) = taken from memo
   |_ fibo(5) = taken from memo
 类似资料:
  • 问题内容: 我在大学为我的Programming II类编写的程序需要一些帮助。这个问题要求人们使用递归来计算斐波那契数列。必须将计算出的斐波那契数存储在一个数组中,以停止不必要的重复计算并减少计算时间。 我设法使程序在没有数组和存储的情况下运行,现在我试图实现该功能,但遇到了麻烦。我不确定如何组织它。我已经浏览了Google并浏览了一些书,但没有太多帮助我解决如何实施解决方案的方法。 上面是不正

  • Python3 实例 以下代码使用递归的方式来生成斐波那契数列: 实例(Python 3.0+)# Filename : test.py # author by : www.runoob.com def recur_fibo(n): """递归函数 输出斐波那契数列""" if n <= 1: return n else: return(recur_fibo(n-1) + recur_fibo(n

  • 问题内容: 请解释以下简单代码: 我对最后一行感到困惑,特别是因为例如,如果n = 5,则将调用fibonacci(4)+ fibonacci(3),依此类推,但我不理解该算法如何以此来计算索引5的值方法。请详细解释! 问题答案: 在斐波那契数列中,每一项都是前两项的总和。因此,你编写了一个递归算法。 所以, 现在你已经知道了。因此,你可以随后计算其他值。 现在, 从斐波那契数列中我们可以看到斐波

  • 我试图想出一个程序,从用户那里获取任何数字,并生成斐波那契码的第n个数字。当我完成工作时,它会显示下一个,而不是我需要的。例如,我正在寻找第11个#和它的生产233而不是144。这是我的代码:

  • 本文向大家介绍Java递归实现斐波那契数列,包括了Java递归实现斐波那契数列的使用技巧和注意事项,需要的朋友参考一下 程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所

  • 我有两种不同的方法,一种是用迭代法计算第n个元素的斐波那契序列,另一种是用递归法。 程序示例如下所示: 我试图找出哪种方法更快。我得出的结论是,对于较小数量的数字,递归速度更快,但随着第n个元素的值增加,递归速度变慢,迭代速度变快。以下是三个不同n的三个不同结果: 示例#1(n=10) 示例#2(n=20) 示例#3(n=30) 我真正想知道的是,为什么迭代突然变得更快,递归变得更慢。如果我错过了