简体   繁体   中英

Printing all paths from a binary tree with python

So I have a pretty dumb question that I can't seem to figure out. I'm just trying to print all paths and how they are being formed from a binary tree using preorder traversal. For that I'm storing each value on a data structure. My question is, why does the behavior change when using string vs using a list when storing each value on the way?

For a Binary Tree with the following definition:

class BinaryTree:
    def __init__(self, value, left_child=None, right_child=None):
        self.value = value
        self.left_child = left_child
        self.right_child = right_child

left_branch = BinaryTree(5, BinaryTree(3, BinaryTree(7), BinaryTree(10)))
right_branch = BinaryTree(8, None, BinaryTree(4, BinaryTree(6), BinaryTree(9)))
root_tree = BinaryTree(1, left_branch, right_branch)

That would look like this:

    1
   / \
  5   8
 /     \
 3     4
/ \   / \
7 10 6   9

When using a string to store and print the values:

def dfs(root, path):
    if root:
        path += str(root.value)
        print(path)
        dfs(root.left_child, path)
        dfs(root.right_child, path)

dfs(root_tree, '')

I get an output:

1
15
153
1537  <-- 1st
15310 <-- 2nd
18
184
1846  <-- 3rd
1849  <-- 4rd

That's ok.

But when I use a list:

def dfs(root, path):
    if root:
        path.append(root.value)
        print(path)
        dfs(root.left_child, path)
        dfs(root.right_child, path)

dfs(root_tree, [])

It doesn't seem to be doing the same thing as it is just storing all nodes on the same path:

[1]
[1, 5]
[1, 5, 3]
[1, 5, 3, 7]                 <-- 1st
[1, 5, 3, 7, 10]             <-- ???
[1, 5, 3, 7, 10, 8]
[1, 5, 3, 7, 10, 8, 4]
[1, 5, 3, 7, 10, 8, 4, 6]
[1, 5, 3, 7, 10, 8, 4, 6, 9]

I can't seem to understand why this is happening.

This is happening because string is an immutable type, while list is mutable.

Now when you pass the strings in the functions (recursively) whenever it gets modified a new instance of the string is created, cause the original string can't be modified. Strings are immutable

However in a list, the modifications done on a list doesn't create a new instance, across the function calls. Python doesn't mind changing the original list, because lists can be modified. Lists are mutable .

This behavior of python while handling lists, can be said to be memory optimization, can also be said to be a pure essence of OOP.

To do the same with list just change the code like this:

def dfs(root, path):
    if root:
        path.append(root.value)
        print(path)
        dfs(root.left_child, path.copy())
        dfs(root.right_child, path.copy())

dfs(root_tree, [])

copy() creates a new list object with non-shared memory with original list

However, doing this makes the program consume more memory than it did before.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM