简体   繁体   中英

Python: Build Binary Tree with Pre and Inorder

I need help completing the recursive part of my function. The function is supposed to use my ListBinaryTree Class to help reconstruct a tree given its inorder and preorder traversal in string format: eg.

preorder = '1234567'
inorder = '3241657' 

def build_tree(inorder, preorder):
    head = preorder[0]
    print(head)
    head_pos = inorder.index(head)
    print(head_pos)
    left_in = inorder[:head_pos]
    print(left_in)
    right_in = inorder[(head_pos+1):]
    print(right_in)
    left_pre = preorder[1:-len(right_in)]
    print(left_pre)
    right_pre = preorder[-len(right_in):]
    print(right_pre)

Which finds the important values in the preorder and inorder traversals and splits the tree up to determine which numbers are for the left side and right side of the tree.

An example of its input and output is:

build_tree('3241657', '1234567')

.

1
3
324
657
234
567

My class that I use to create the tree is as follows:

class ListBinaryTree:
"""A binary tree class with nodes as lists."""
DATA = 0    # just some constants for readability
LEFT = 1
RIGHT = 2   

def __init__(self, root_value, left=None, right=None):
    """Create a binary tree with a given root value
    left, right the left, right subtrees        
    """ 
    self.node = [root_value, left, right]

def create_tree(self, a_list):
    return ListBinaryTree(a_list[0], a_list[1], a_list[2])

def insert_value_left(self, value):
    """Inserts value to the left of this node.
    Pushes any existing left subtree down as the left child of the new node.
    """
    self.node[self.LEFT] = ListBinaryTree(value, self.node[self.LEFT], None)

def insert_value_right(self, value):
    """Inserts value to the right of this node.
    Pushes any existing left subtree down as the left child of the new node.
    """      
    self.node[self.RIGHT] = ListBinaryTree(value, None, self.node[self.RIGHT])

def insert_tree_left(self, tree):
    """Inserts new left subtree of current node"""
    self.node[self.LEFT] = tree

def insert_tree_right(self, tree):
    """Inserts new left subtree of current node"""
    self.node[self.RIGHT] = tree

def set_value(self, new_value):
    """Sets the value of the node."""
    self.node[self.DATA] = new_value

def get_value(self):
    """Gets the value of the node."""
    return self.node[self.DATA]

def get_left_subtree(self):
    """Gets the left subtree of the node."""
    return self.node[self.LEFT]

def get_right_subtree(self):
    """Gets the right subtree of the node."""
    return self.node[self.RIGHT]

def __str__(self):
    return '['+str(self.node[self.DATA])+', '+str(self.node[self.LEFT])+', '+\
 str(self.node[self.RIGHT])+']'

For the recursive part of the function I tried doing something like:

my_tree= ListBinaryTree(head)
while my_tree.get_value() != None:
        left_tree = build_tree(left_in, left_pre)
        right_tree = build_tree(right_in, right_pre)
        my_tree.insert_value_left(left_tree)
        my_tree.insert_value_right(right_tree)
    print (my_tree)

But it returns an "index out of range" error.

Also for something like:

def build_tree(inorder, preorder):
    head = preorder[0]
    head_pos = inorder.index(head)
    left_in = inorder[:head_pos]
    right_in = inorder[(head_pos+1):]
    left_pre = preorder[1:-len(right_in)]
    right_pre = preorder[-len(right_in):]
    if left_in:
        left_tree = build_tree(left_in, left_pre)
    else:
        left_tree = None
    if right_in:
        right_tree = build_tree(right_in, right_pre)
    else:
        right_tree = None
    my_tree =  ListBinaryTree(head, left_tree, right_tree)
    print(my_tree)

input

build_tree('3241657', '1234567')

returns

[3, None, None]
[4, None, None]
[2, None, None]
[6, None, None]
[7, None, None]
[5, None, None]
[1, None, None]    

Can anyone please help me with the recursive part?

Thanks

You're making the recursive part much harder than necessary.

if left_in:
    left_tree = build_tree(left_in, left_pre)
else:
    left_tree = None

if right_in:
    right_tree = build_tree(right_in, right_pre)
else:
    right_tree = None

return ListBinaryTree(head, left_tree, right_tree)

You could perhaps simplify it even further by moving the checks for empty sequences up to the top of the function (eg if not inorder: return None ) so it only needs to appear once.

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