# Python data structure and algorithm tree

### Definition of tree

In computer science, tree is a kind of abstract data type or a data structure to realize this kind of abstract data type, which is used to simulate the data set with tree structure. It is a set of n (n > 0) finite nodes with hierarchical relationship. It's called "tree" because it looks like an upside down tree, that is, it's root up and leaf down. It has the following characteristics

• Each node has zero or more child nodes;
• A node without a parent node is called a root node;
• Each non root node has only one parent node;
• In addition to the root node, each sub node can be divided into multiple disjoint sub trees; ### Tree is implemented by list

Idea: for a list:['q ', [], []], it represents a tree (subtree),' Q 'is the root node, [], [] are left and right child nodes respectively. Therefore, a tree with a left node of 'a' can be written as ['q',['a', [], []], []]. In this case, the root node is my_tree, left node is my_tree, the right node is my_tree.

Example: my_tree = ['a', ['b', ['d',[],[]], ['e',[],[]] ], ['c',['f',[],[]], []] ]

``````
def binary_tree(root):
return [root, [], []]

def insert_left(root, new_branch):
t = root.pop(1)

if len(t) > 0:
root.insert(1, [new_branch, t, []])
else:
root.insert(1, [new_branch, [], []])

def insert_right(root, new_branch):
t = root.pop(2)

if len(t) > 0:
root.insert(2, [new_branch, [], t])
else:
root.insert(2, [new_branch, [], []])

def get_root_value(root):
return root

def set_root_value(root, value):
root = value

def get_left_value(root):
return root

def get_right_value(root):
return root

``````

### Chain structure implementation tree ``````
class LinkedTree:
def __init__(self, obj):
self.__key = obj
self.__left_child = None
self.__right_child = None

def insert_left_child(self, new_node):
if self.__left_child == None:
self.__left_child = LinkedTree(new_node)
else:
t = LinkedTree(new_node)
t.__left_child = self.__left_child
self.__left_child = t

def insert_right_child(self, new_node):
if self.__right_child == None:
self.__right_child = LinkedTree(new_node)
else:
t = LinkedTree(new_node)
t.__right_child = self.__right_child
self.__right_child = t

def get_root_value(self):
return self.__key

def set_root_value(self, value):
self.__key = value

def get_left_child(self):
return self.__left_child

def get_right_child(self):
return self.__right_child

def preorder(self):
print(self.__key)

if self.__left_child:
self.__left_child.preorder()

if self.__right_child:
self.__right_child.preorder()

def middleorder(self):
if self.__left_child:
self.__left_child.middleorder()

print(self.__key)

if self.__right_child:
self.__right_child.middleorder()

def postorder(self):
if self.__left_child:
self.__left_child.postorder()

if self.__right_child:
self.__right_child.postorder()

print(self.__key)

``````

### Application of tree

#### Building an expression tree

The analytic expression can be expressed as a tree, for example: ((7 + 3) * 5 − 2)) can be expressed as The formation of the parse tree can be defined as the following four rules:

1. If (, which means there is a new expression, create a new subtree (add a new sub node, and then create the left sub node of the new node, and move the processing target to the left sub node)

2. If [+, -, *, /] operators are encountered, place this operator on the current node, create a right child node, and move the processing target to this right child node

3. If a number is encountered, place the number in the current node and return the processing target to the parent node

4. If encountered), return the processing target to the parent node.

``````
def build_exp_tree(fpexp):
fplist = fpexp.split()
fp_stack = Stack()
etree = LinkedTree('')
fp_stack.push(etree)
current_tree = etree

for i in fplist:
if i == "(":
current_tree.insert_left_child('')
fp_stack.push(current_tree)
current_tree = current_tree.get_left_child()
elif i not in ['+', '-', '*', '/', ')']:
current_tree.set_root_value(int(i))
parent = fp_stack.pop()
current_tree = parent
elif i in ['+', '-', '*', '/']:
current_tree.set_root_value(i)
current_tree.insert_right_child('')
fp_stack.push(current_tree)
current_tree = current_tree.get_right_child()
elif i == ')':
current_tree = fp_stack.pop()
else:
raise ValueError()

return etree

``````

Because the binary tree class constructed between cannot access its parent node, a new stack should be built here to store the current parent node.

In the case of (and operators, both operations need to move the current operation node to the left and right children, so these two operations need to stack the parent node.

Solving expressions

``````import operator

def evaluate(expression_tree):
opers = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv
}

res1 = res2 = None

if expression_tree:
res1 = evaluate(expression_tree.get_left_child())
res2 = evaluate(expression_tree.get_right_child())

if res1 and res2:
return opers[expression_tree.get_root_value](res1, res2)
else:
return expression_tree.get_root_value()

``````

Tags: Programming

Posted on Mon, 08 Jun 2020 22:56:52 -0400 by johnc71