This question is for school (homework) so I am not asking for code, and I don't want any, just an idea. I have to write a function that returns two lists, a list of the leaves and a list of the internal nodes of a binary tree. My algorithm is:
1) If both the left and the right subtrees are None, it is a leaf, and so I add it to the leaves list.
2) If they are not, then I add it to the internals list, and call the function on the left subtree, and then on the right, if they exist.
This is the code I have written:
def leaves_and_internals(self): leaves =  internals =  if self.left is None and self.right is None: leaves.append(self.item) else: internals.append(self.item) if self.left != None: leaves_and_internals(self.left) else: leaves_and_internals(self.right) return internals, leaves
I'm pretty sure that the algorithm is correct, but I think that every time I recurse on the Nodes, the lists will get reset. How can I get around this?
Any help is greatly appreciated. Thanks
I have not looked into the algorithm of your code, and just merely suggesting an answer to the problem you're stuck at. You could pass leaves and internals as arguments to the recursive function, so that their contents get retained across the recursive calls.
In python, if you pass a mutable object to a function/method, the function/method gets a reference to the object. So as long as you still treat it as the same mutable object (i.e. not assign the parameter with something else directly), any changes you make to the object are also visible to the caller. Since list is a mutable type, this behavior is very much helpful for the case you're interested in.
And make sure to initialize the lists to  before calling the leaves_and_internals function from outside.
def leaves_and_internals(self, leaves, internals): if self.left is None and self.right is None: leaves.append(self.item) else: internals.append(self.item) if self.left != None: leaves_and_internals(self.left, leaves, internals) else: leaves_and_internals(self.right, leaves, internals) return # Somewhere outside leaves =  internals =  myobj.leaves_and_internals(leaves, internals)
Since the OP mentions he cannot change the signature of the method nor use instance variables, this is an alternate solution I can think of which returns the leaves and internals to the caller. BTW, I assume some nodes in your tree can have both left and right, so you would need to check both (i.e. use 2 separate if instead of an if...else).
def leaves_and_internals(self): leaves =  internals =  if self.left is None and self.right is None: leaves = [ self.item ] else: if self.left != None: leaves, internals = leaves_and_internals(self.left) if self.right != None: templeaves, tempinternals = leaves_and_internals(self.right) leaves += templeaves internals += tempinternals internals.append(self.item) return leaves, internals