NameError When Implementing Inorder Traversal - python

I'm trying to implement a Binary Search Tree in Python, and I'm having difficulty in understanding the NameError I get when I call the inorder traveral method on my tree. I have already created a BST instance, and I've defined the in_order_traversal() method before I call it on the instance, so why am I getting a NameError?
class BSTNode:
def __init__(self,data):
self.data = data
self.left = None
self.right = None
class BST:
def __init__(self):
self.root = None
def insert(self,data):
new_node = BSTNode(data)
if self.root == None:
self.root = new_node
else:
ptr = self.root
prev = None
while ptr != None:
prev = ptr
if data <= ptr.data:
ptr = ptr.left
else:
ptr = ptr.right
if data <= prev.data:
prev.left = new_node
else:
prev.right = new_node
def in_order_traversal(self):
if self.root != None:
in_order_traversal(self.root.left)
print(root.data)
in_order_traversal(self.root.right)
bst = BST()
bst.insert(50)
bst.insert(25)
bst.insert(100)
bst.insert(80)
bst.insert(30)
bst.in_order_traversal()

You forgot the self.
def in_order_traversal(self):
if self.root != None:
self.in_order_traversal(self.root.left)
print(root.data)
self.in_order_traversal(self.root.right)

Related

What is difference between is_empty and is_empty() in Single Linked List in python?

i have created Single Linked List in python and i want to know what '()' mainly functions in def delete_front(self).
Here is my Code.
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
class SLinkedList(object):
def __init__(self):
self.head = None
self.size = 0
def size(self):
return self.size
def is_empty(self):
if self.size==0:
return True
else:
return False
def search(self,target):
return
def insert_front(self, data):
nw_node = Node(data)
if self.is_empty():
self.head = nw_node
else:
nw_node.next = self.head.next
self.head.next = nw_node
#p is pointer
def insert_after(self, data, p):
nw_node = Node(data)
if p==self.size:
p.next = nw_node
else:
nw_node.next = p.next
p.next = nw_node
def delete_front(self):
if is_empty():
return None
else:
tmp_node =self.head.next
tmp_node.prev = self.head
self.head.next = tmp_node.next
def delete_after(self, p):
if p==self.size:
return None
else:
tmp_node = p.next
p.next = tmp_node.next
def print_list(self):
node = self.head
while node:
print(node)
node = node.next

How to get the length of a tree in python binary search

class Node:
def __init__(self,data=None):
self.data=data
self.left_child=None
self.right_child=None
self.parent=None
self.root = None
class BinarySearchTree:
def __init__(self):
self.root=None
def add(self, data):
if self.root == None:
self.root = Node(data)
else:
self.add_helper(data, self.root)
def add_helper(self, data, cur_node):
if data < cur_node.data:
if cur_node.left_child == None:
cur_node.left_child = Node(data)
cur_node.left_child.parent = cur_node # set parent
else:
self.add_helper(data, cur_node.left_child)
elif data > cur_node.data:
if cur_node.right_child == None:
cur_node.right_child = Node(data)
cur_node.right_child.parent = cur_node # set parent
else:
self.add_helper(data, cur_node.right_child)
else:
print("data already in tree!")
def __len__(self):
if self.root is None:
return 0
else:
return (self.__len__(self.left_child) + 1 +self. __len__(self.right_child))
So i am trying to return the length of the binary search tree list, so i tried using the len method for my binary search tree class. However, this is not working correctly. I need it to be able to not take in any parameters, and just return an integer for the length of the binary search tree list. What am i missing and what am i doing wrong here?
You will need a helper function that takes a Node argument. Then do the recursion on the left and right of the node.
def __len__(self):
return self.tree_len(self.root)
def tree_len(self, node):
if node is None:
return 0
else:
return 1 + max(self.tree_len(node.right_child), self.tree_len(node.left_child))

Python insert node function

I am having a really hard time understanding how to properly fix my insert node function. I am not receiving any errors but I am also not displaying the list.
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Solution:
def display(self, head):
current = head
while current:
print current.data,
current = current.next
def insert(self, head, data):
self.head = head
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
new_node.next = self.head
self.head = new_node
mylist = Solution()
T = int(input())
head = None
for i in range(T):
data = int(input())
head = mylist.insert(head, data)
mylist.display(head)
Your insert() didn't return anything. So head will be None if you assign returned value to it.
I think this is you want
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Solution:
def __init__(self):
self.head = None
def display(self):
current = self.head
while current:
print current.data,
current = current.next
def insert(self, data):
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
new_node.next = self.head
self.head = new_node
mylist = Solution()
T = int(input())
for i in range(T):
data = int(input())
mylist.insert(data)
mylist.display()

How can I make a tree Node object display its contents when printed?

This error is occurring when we call the lookup method. Can anyone say how can it be rectified? I am unable to debug it using the available documents online. This is an implementation of a binary tree class. I know it is something related to the equivalence problem.
import deque
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
def insert(self, data):
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
else:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
def lookup(self, data, parent=None):
if self.data == data:
return self, parent
if data < self.data:
if self.left is None:
return None
else:
return self.left.lookup(data, parent=self)
else:
if self.right is None:
return None
else:
return self.right.lookup(data, parent=self)
# aka bfs traversal
def level_traversal(self):
root = self
dq = deque()
dq.append(root)
while dq:
root = dq.popleft()
if root.left:
dq.append(root.left)
if root.right:
dq.append(root.right)
print (root.data)
def delete(self, data):
node, parent = self.lookup(data)
if node.children_count() == 0:
if parent.left == node:
parent.left = None
else:
parent.right = None
del node
elif node.children_count() == 1:
if node.left:
n = node.left
else:
n = node.right
if parent:
if parent.left == node:
parent.left = n
else:
parent.right = n
del node
else:
# find the successor
parent = node
successor = node.right
while successor.left:
parent = successor
successor = successor.left
node.data = successor.data
if parent.left == successor:
parent.left = successor.right
else:
parent.right = successor.right
def inorder(self):
if self.left:
self.left.inorder()
print (self.data)
if self.right:
self.right.inorder()
def preorder(self):
print (self.data)
if self.left:
self.left.preorder()
if self.right:
self.right.preorder()
def postorder(self):
if self.left:
self.left.postorder()
if self.right:
self.right.postorder()
print (self.data)
root = Node(8)
root.insert(3)
root.insert(10)
root.insert(1)
root.insert(6)
root.insert(4)
root.insert(7)
root.insert(14)
root.insert(13)
# look up
print (root.lookup(6))
# level traversal
root.level_traversal()
#mirror image
#root.mirror_image()
#root.delete(3)
#root.level_traversal()
# inorder
#root.inorder()
# pre order
#root.preorder()
# postorder
#root.postorder()
# size
#root.size()
#root.dfs()
#print root.height()
This is not an error at all. This happens because you are returning a tuple of objects from your lookup method, and this is just how objects are represented when you print them out. If you don't like this, you can overwrite the __repr__() method.
Try this in your class definition.
Definition for a binary Tree Node
class TreeNode:
def __init__(self, val = 0, left = None, right = None):
self.val = val
self.left = left
self.right = right
## print TreeNode Object
def __repr__(self) -> str:
return '[%s, %r, %r]' % (self.val, self.left, self.right)

How to call a class method using an instance of a different class in Python?

I am a trying to implement a binary tree using two classes - Node and Binary Tree. When I am inserting the nodes (left or right), I am using the methods insert_left_node and insert_right_node which are class BinaryTree's methods, but I am also using class Node to create a node. After every node insertion, the current object is returned.
Now, how do I call class BinaryTree's insertion methods using the returned object - current. E.g. In the second last line of the code, statement n3 = n1.insert_left_node(33) fails with AttributeError: 'Node' object has no attribute 'insert_left_node'
I need an alternative way to achieve this.
Code:
class Node(object):
def __init__(self, data):
self.data = data
self.left = None
self.right = None
class BinaryTree(object):
def __init__(self, root=None):
self.root = Node(root)
def insert_left_node(self, data):
if not self.root:
self.root = Node(data)
else:
current = self.root
while True:
if current.left:
current = current.left
else:
current.left = Node(data)
break
return current
def insert_right_node(self, data):
if not self.root:
self.root = Node(data)
else:
current = self.root
while True:
if current.right:
current = current.right
else:
current.right = Node(data)
break
return current
if __name__ == '__main__':
r = BinaryTree(34) # root
n1 = r.insert_left_node(22)
n2 = r.insert_right_node(45)
n3 = n1.insert_left_node(33) # Fails
print n3
Your request literally doesn't make any sense. To achieve what you want you should just add the needed methods to the class you want to use. Try something similar to the following:
class Node(object):
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def insert_left_node(self, data):
self.left = Node(data)
def insert_right_node(self, data):
self.right = Node(data)

Categories