i am trying to invert a binary tree, but when i print, nothing changes.
my strategy is to the nextSibling a prevSibling. that means, i need to reverse the linked-list, but here i am just using nodes, not linked-lists. please help
class treeNode:
def __init__(self,data):
self.data = data
self.children = []
self.parent = None
self.nextSibling = None
self.level = 0
self.prevSibling = None
def add_children(self,*child):
for i in child:
i.parent = self
self.children.append(i)
if len(self.children) > 1:
self.children[-2].nextSibling = i
i.prevSibling = self.children[-2]
class Tree:
def __init__(self,root:treeNode):
self.root = root
self.depth = 0
def invert_tree(self):
self.root.children = self.root.children[::-1]
kid = self.root.children[0]
while kid != self.root:
if len(kid.children) == 0:
while kid.parent:
if kid.prevSibling:
kid = kid.prevSibling
break
else:
kid = kid.parent
else:
kid.children = kid.children[::-1]
kid = kid.children[0]
parent = treeNode(1)
child = treeNode(2)
grand = treeNode(3)
parent.add_children(child,treeNode(22))
child.add_children(grand,treeNode(33))
grand.add_children(treeNode(4))
tree = Tree(parent)
tree.print_tree()
tree.invert_tree()
this is the output i get:
1
|__ 22
thanks in advance :)
Related
I am trying to make AI for board game with minimax algorithm, but I have problem with creating a tree structure. I know that you actually don't need to build tree for minimax but I have to. I want to build Tree separately from minimax and then use minimax on that tree. I don't know how to do it so that is what I need help for. Thanks in advance.
So I tried this:
from queue import Queue
class TreeNode(object):
__slots__ = 'parent', 'children', 'data', 'player'
def __init__(self, data, player):
self.parent = None
self.player = player
self.children = []
self.data = data
def is_root(self):
return self.parent is None
def is_leaf(self):
return len(self.children) == 0
def add_child(self, x):
x.parent = self
self.children.append(x)
def print_tree(self):
print(' '*self.get_level() + '|--', end = '')
print(self.data)
if self.children:
for each in self.children:
each.print_tree()
def get_level(self):
level = 0
p = self.parent
while p :
p = p.parent
level += 1
return level
class Tree(object):
def __init__(self):
self.root = None
And I tried with recursion to create Tree. Board is Hash map representing state of board(initially is empty and it should be root, root children should be all possible moves on empty board and so on)
def make_tree(self,board, player, depth):
list_possible_moves = self.possible_moves()
last_move = []
t = Tree()
t.root = TreeNode(board,None)
if depth > 0:
node = TreeNode(board,player)
board2 = deepcopy(self._board)
player = player * -1
for i in range(len(list_possible_moves)):
board2 = deepcopy(board2)
if len(last_move) != 0 :
board2.set_val(last_move[-1],"0")
if player == 1:
board2.set_val(i,"W")
else:
board2.set_val(i,"B")
child = TreeNode(board2,player)
if child.get_level == 1:
t.root.add_child()
else:
node.add_child(child)
if player == 1 :
self.make_tree(board2,1,depth-1)
if player == -1 :
self.make_tree(child,-1,depth-1)
else :
return None
But it is not working, and it takes 6-10 seconds to make tree.
While I was learning Tree data structure in python, I came across this code:
class TreeNode:
def __init__(self, data):
self.data = data
self.children = []
self.parent = None
def get_level(self):
level = 0
p = self.parent
while p:
level += 1
p = p.parent
return level
def print_tree(self):
spaces = ' ' * self.get_level() * 3
prefix = spaces + "|__" if self.parent else ""
print(prefix + self.data)
if self.children:
for child in self.children:
child.print_tree()
def add_child(self, child):
child.parent = self
self.children.append(child)
def build_product_tree():
root = TreeNode("Electronics")
laptop = TreeNode("Laptop")
laptop.add_child(TreeNode("Mac"))
laptop.add_child(TreeNode("Surface"))
laptop.add_child(TreeNode("Thinkpad"))
cellphone = TreeNode("Cell Phone")
cellphone.add_child(TreeNode("iPhone"))
cellphone.add_child(TreeNode("Google Pixel"))
cellphone.add_child(TreeNode("Vivo"))
tv = TreeNode("TV")
tv.add_child(TreeNode("Samsung"))
tv.add_child(TreeNode("LG"))
root.add_child(laptop)
root.add_child(cellphone)
root.add_child(tv)
root.print_tree()
if __name__ == '__main__':
build_product_tree()
It was a tutorial from Codebasics: https://www.youtube.com/watch?v=4r_XR9fUPhQ&list=PLeo1K3hjS3uu_n_a__MI_KktGTLYopZ12&index=9
Now my question is why in the 25th line there is child.parent = self what does it mean or why should I have to do that.
self references the current instance. This line of code will tell the child that it's parent is the current instance.
I created a function that inserts a node to its correct position.
For example:
root = converts_list_to_linked_list([4, 7, 9, 14]) #I have a linked list: 4->7->9->14
The Function:
insert_ordered(root, 12)
returns a linked list of "4->7->9->12->14->None"
class LN:
def __init__(self, value):
self.value = value
self.next = None
def insert_ordered(root, data):
node = LN(data)
if root == None:
return node
else:
if root.value > data:
node.next = root
return node
else:
temp, prev = root, None
while temp.next and temp.value <= data:
prev = temp
temp = temp.next
if temp.next == None and temp.value <= data:
temp.next = node
else:
node.next = prev.next
prev.next = node
return root
Is there any way to solve this problem recursively? I can't grasp the idea on how too.
Try this:
class LN:
def __init__(self, value, node=None):
self.value = value
self.next = node
def insert_ordered(root, data):
if root == None or root.value > data:
return LN(data, root)
root.next = insert_ordered(root.next, data)
return root
If you want to insert in descending order change root.value > data to root.value < data
The following uses an auxiliary function to recursively insert into the list:
class LN:
def __init__(self, value):
self.value = value
self.next = None
def insert_ordered(self, data):
node = LN(data)
return self.insert_ordered_aux(node)
def insert_ordered_aux(self,node):
if self.value >= node.value: # add node before current node
node.next = self
return node
elif self.next: # do the recursion
self.next = self.next.insert_ordered_aux(node)
return self
else: # add node at end of list
self.next = node
return self
#test:
root = LN(4)
root = root.insert_ordered(9)
root = root.insert_ordered(14)
root = root.insert_ordered(6)
root = root.insert_ordered(-2)
root = root.insert_ordered(12)
def print_list(node):
if (node):
print(node.value)
print_list(node.next)
print_list(root)
How are you using it, and is your pasted code's indentation correct?
After some indentation adjustments, this is how i use it, and what i get:
class LN:
def __init__(self, value):
self.value = value
self.next = None
def insert_ordered(root, data):
node = LN(data)
if root == None:
return node
else:
if root.value > data:
node.next = root
return node
else:
temp, prev = root, None
while temp.next and temp.value <= data:
prev = temp
temp = temp.next
if temp.next == None and temp.value <= data:
temp.next = node
else:
node.next = prev.next
prev.next = node
return root
#Use:
a1 = LN(1)
a1.next = a2 = LN(5)
a2.next = a3 = LN(10)
a3.next = a4 = LN(15)
root = a1
#Insert tests
root = root.insert_ordered(13)
root = root.insert_ordered(12)
root = root.insert_ordered(15)
root = root.insert_ordered(-5)
root = root.insert_ordered(17)
t = root
while(t):
print(str(t.value) + " ")
t = t.next
Output:
-5
1
5
10
12
13
15
15
17
I'm trying to implement a serializing/deserializing algorithm in python for binary trees.
Here's my code:
class Node:
count = 1
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def insert(self, value):
if self.value > value:
if self.left is None:
self.left = Node(value)
Node.count += 1
else:
self.left.insert(value)
else:
if self.right is None:
self.right = Node(value)
Node.count += 1
else:
self.right.insert(value)
# Using preorder
def serialize(root, serial):
if root != None:
serial.append(root.value)
serialize(root.left, serial)
serialize(root.right, serial)
else:
serial.append('x')
def deserialize(newRoot, serial):
if serial[0] == 'x':
serial.pop(0)
else:
if len(serial) > 0:
newRoot = Node(serial.pop(0))
print(newRoot.value)
deserialize(newRoot.left, serial)
deserialize(newRoot.right, serial)
print("This program serializes a tree\n")
root = Node(3)
root.insert(1)
root.insert(2)
root.insert(4)
root.insert(5)
root.insert(0)
# Serialize
serial = []
serialize(root, serial)
print(serial)
# Deserialize
newRoot = Node(None)
deserialize(newRoot, serial)
print(newRoot.value)
The problem is, newRoot doesn't get updated by deserialize because python passes it by value. How do I get around this, preferably in the most elegant way? In C/C++, I would just pass a pointer to newRoot and it should get updated accordingly. Thanks!
You can return the newly created nodes and assign them as left and right nodes. Also poping the first element of a list is more costly than poping the last element, so reverseing the list at the beginning and then using it in the recursion will be more performant in your case. So the code will become something like:
def deserialize(serial):
serial.reverse()
return _deserialize(serial)
def _deserialize(serial):
if not serial:
return None
node = None
value = serial.pop()
if value != 'x':
node = Node(value)
node.left = _deserialize(serial)
node.right = _deserialize(serial)
return node
root = deserialize(serial)
print(root.value)
You can create left and right subtree within deserialize function and return the root.
Here is my code:
node_list = []
MARKER = -1
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def serialize(root):
if root is None:
node_list.append(MARKER)
return
node_list.append(root.val)
serialize(root.left)
serialize(root.right)
def deserialize(root, node_list):
if node_list:
val = node_list.pop(0)
else:
return
if val == MARKER:
return
# Create root, left and right recursively
root = Node(val)
root.left = deserialize(root.left, node_list)
root.right = deserialize(root.right, node_list)
return root
def inorder_traversal(root):
if root:
inorder_traversal(root.left)
print(root.val, end=' ')
inorder_traversal(root.right)
if __name__=="__main__":
# Create tree
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
print("Inorder traversal before serialization..")
inorder_traversal(root)
print('')
# serialize the tree and insert elements into a list
serialize(root)
print(node_list)
root1 = None
root1 = deserialize(root1, node_list)
print("Inorder traversal after deserialization..")
inorder_traversal(root1)
print('')
I am learning python as one my project requirements is to print a binary tree.
I am trying out my code to print the tree path.
It just stops at root node.
I am trying to find where I messed up.
Tree:
A
/ \
B C
/ / \
D E F
The output I want is:
ABD
ACE
ACF
class Node(object):
def __init__(self, data):
self.data = data
self.children = []
self.val = data
self.left = None
self.right = None
r = Node('A')
r.left = Node('B')
r.right = Node('C')
r.left.left = Node('D')
r.right.right = Node('E')
The above should be r.right.left = Node('E)
r.right.right = Node('F')
def binaryTreePaths(root):
results = []
c = []
binary_tree_paths(root, c, results)
return results
def binary_tree_paths(root, cand, res):
if root is None:
return
else:
cand.append(str(root.val)+" ")
if root.left is None and root.right is None:
p = ''.join(map(str, cand))
res.append(p)
binary_tree_paths(root.left, cand, res)
binary_tree_paths(root.right, cand, res)
cand.pop()
print binaryTreePaths(r)
You should have r.right.left = Node('E'), instead of r.right.right = Node('E')