4

Hope someone can help, I'm not a programmer, but have been interested in exploring Fibonacci sequence and it's recursive tree...

I've created a Binary Tree class, along with an associated TreeNode class, and want to generate a binary tree of the recursive calls created by:

f(n) = f(n-1) + f(n-2) for a given value of n

I'd want to add it as an InsertFibonacci method of my Binary Tree class, replacing the standard Insert method:

def insertNode(self, root, inputData):
    if root == None:
        return self.addNode(inputData)
    else:
        if inputData <= root.nodeData:
            root.left = self.insertNode(root.left, inputData)
        else:
            root.right = self.insertNode(root.right, inputData)
        return root

Would I add somekind of decorator to the Fib function?

# Fib function
def f(n):

    def helper(n):
        left = f(n-1)
        right = f(n-2)
        return left,right

    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        left, right = helper(n)
        return left + right
juliomalegria
  • 24,229
  • 14
  • 73
  • 89
Alex2134
  • 557
  • 7
  • 22
  • Do you mean you want a data structure to represent the call graph for the recursive Fibonacci function? Then you shouldn't be using a binary *search* tree. – Fred Foo Feb 11 '12 at 00:14
  • Hi Larsmans, Yes, a data structure to represent the call graph. Doesn't the call graph represent a near complete strict binary tree structure though? – Alex2134 Feb 11 '12 at 00:20
  • 1
    Yes, but the call graph is not a binary *search* tree, which is what `insertNode` seems to implement. A BST is a labeled binary tree with ordering constraints that the Fibonacci call graph does not exhibit. – Fred Foo Feb 11 '12 at 00:24
  • Right, I understand the distinction. Many thanks for clarifying. – Alex2134 Feb 11 '12 at 00:55

2 Answers2

3

Here's the simplest solution I can think of:

class FibTree(object):
    def __init__(self, n):
        self.n = n
        if n < 2:
            self.value = n
        else:
            self.left = FibTree(n - 1)
            self.right = FibTree(n - 2)
            self.value = self.left.value + self.right.value
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Many thanks Tzaman and Larsmans for your fast answers! I'll try out these solutions. – Alex2134 Feb 11 '12 at 00:27
  • Many thanks @larsmans I've used your FibTree class and it works well. I've amended it, so each node includes a reference to it's parent: class FibTree(object): def __init__(self, n, parent): self.n = n self.parent = parent if n < 2: self.value = n self.left = None self.right = None else: self.left = FibTree(n - 1, self) self.right = FibTree(n - 2, self) self.value = self.left.value + self.right.value I'd like to be able to ascertain for a given node whether it's a left or right sibling of it's parent. Is this possible, through the parent node link? Thanks Alex – Alex2134 Feb 11 '12 at 17:30
  • how would it be possible to ascertain, given a node n, to test whether is Left or Right? – Alex2134 Feb 12 '12 at 16:53
  • 1
    Just like I posted in my previous comment. `def is_left_child(self): return self is self.parent.left` (+ catch the exception raised when calling this on the root). – Fred Foo Feb 12 '12 at 18:05
  • Thanks @larsmans. I slightly amended this for integration into the Class you intially setout: `def is_left_child(self, root): """ Returns true if Node is a left child """ if root.parent: The next thing I need to figure out is out to graphically visualise the tree hierarchy, showing parent-child relationships. Currently I've just done a breadth first traversal, but this only gives me children on each level and not relationships. Thanks Alex return root is root.parent.left else: return False` – Alex2134 Feb 17 '12 at 22:22
  • Sorry about the above comment, my mark-up got somewhat screwed up and ran out of editing time! – Alex2134 Feb 17 '12 at 22:29
1

Here's one way:

def insertFibonacci(self, n):
    current = self.addNode(n)
    if n > 1:
        current.left = self.insertFibonacci(n-1)
        current.right = self.insertFibonacci(n-2)
        # if you want the fibonacci numbers instead of the calls:
        # current.value = current.left.value + current.right.value
    return current

Assumes positive n. Should return the root of the fibonacci call tree.

Note that this won't exactly be the same kind of binary tree; it won't satisfy the ordering invariant that a binary search tree does. I'm assuming you just want to use your existing structure for convenience.

tzaman
  • 46,925
  • 11
  • 90
  • 115
  • Many thanks @larsmans I've used your FibTree class and it works well. I've amended it, so each node includes a reference to it's parent: – Alex2134 Feb 11 '12 at 17:26