Trouble creating my binary tree data structure [Python] - python

This is what I have so far. I am rather confused, what am I missing here? Is it standard to do Node.left = Node(5)? I think confusing. Should I have a addLeft function in the Tree class that does that for me? Little confused on standard tree implementation.
class Node:
def __init__(self,val):
self.val = val
self.right = None
self.left = None
class Tree:
def __init__(self):
self.root = None
t = Tree()
t.root = (Node(3))
print t.root.val

Related

AttributeError: type object 'BSTNode' has no attribute 'left'

I was trying to construct a Binary Search Tree in python.
This is my node class:
class BSTNode:
def __init__(self,val):
self.left = None
self.right = None
self.val = val
This class contains a function called printTree, which is supposed to print the tree inorder. Here is the printTree function:
def printTree(self,val):
if self.left is not None:
self.left.printTree()
print(self.val)
if self.right is not None:
self.right.printTree()
When I execute the function it gives AttributeError: type object 'BSTNode' has no attribute 'left'
Here is my full code:
class BSTNode:
def __init__(self,val):
self.left = None
self.right = None
self.val = val
def insertNode(self,val):
if self.val:
if val < self.val:
if self.left is None:
self.left = BSTNode(val)
else:
self.left.insertNode(val)
else:
if self.right is None:
self.right = BSTNode(val)
else:
self.right.insertNode(val)
else:
self.val = val
def findval(self,fval):
if (fval == self.val):
print(str(self.val)," data found ")
elif(fval < self.val):
if self.left is None:
print(str(self.val)," data not found")
else:
self.left.findval(fval)
else:
if self.right is None:
print(str(self.val)," data not found")
else:
self.right.findval(fval)
def printTree(self,val):
if self.left is not None:
self.left.printTree()
print(self.val)
if self.right is not None:
self.right.printTree()
root = BSTNode(12)
root.insertNode(6)
root.insertNode(5)
root.insertNode(18)
root.insertNode(15)
root.insertNode(21)
BSTNode.printTree(BSTNode)
You are calling printTree() without arguments:
self.left.printTree()
...
self.right.printTree()
Yet, you defined it to accept val, which is just unused by the way:
def printTree(self,val):
Replace it to:
def printTree(self):
The method printTree() is an instance method, not a #classmethod nor #staticmethod. That means it requires an active instance/object of BSTNode to be called which will be passed as the self argument. So this call is incorrect:
BSTNode.printTree(BSTNode)
It must be:
root.printTree(BSTNode)
Then considering my point-1 above, finally it should be:
root.printTree()
Where root is your current active instance of type BSTNode.
After those fixes, it would be successful
5
6
12
15
18
21
Alternative Solution
If you don't want printTree() to be an instance method, make it a #staticmethod instead.
class BSTNode:
...
#staticmethod
def printTree(self): # I named it self to be close to your real implementation. Ideally, rename it to something like "node" or "obj" to avoid confusion since this is not an instance method.
if self.left is not None:
self.printTree(self.left)
print(self.val)
if self.right is not None:
self.printTree(self.right)
...
BSTNode.printTree(root)
This will produce the same output.

Recursion within a method

In my code I am counting the number of nodes in a complete binary tree and I decided to use a recursive approach. However, when I call my method within itself, I get NameError: name 'countNodes' is not defined.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def countNodes(self, root: TreeNode, count = 0) -> int:
if not root.left and not root.right:
return 1
else:
count += countNodes(self, root.left, count) + countNodes(self, root.right, count)
To answer this question.
When accessing a method of the class instance inside the class you have to use self.method. So in your case you have to use self.countNodes instead of countNodes.

Binary search tree python with OOP

I'm trying to understand python and OOP along with data structures
I'm now looking at the implementation of a binary search tree
here is the class for the node structure
class Node():
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
the developer of this code has created the insert feature in Node class and in another class called tree
here is what it looks like in the node class :
def insert(self, data):
if self.data == data:
return False
elif data < self.data:
if self.leftChild:
return self.leftChild.insert(data)
else:
self.leftChild = Node(data)
return True
else:
if self.rightChild:
return self.rightChild.insert(data)
else:
self.rightChild = Node(data)
return True
however, he created a function with the same name in the tree class which looks like this
class Tree():
def __init__(self):
self.root = None
def insert(self, data):
if self.root:
return self.root.insert(data)
else:
self.root = Node(data)
return True
I do have some questions at this point, why are there 2 functions with the same name? and when I try to execute one of them without the other on this code it shows an error
if __name__ == '__main__':
tree = Tree()
tree.insert(10)
why does he made instance for tree not for node ?
can someone please explain those concepts for me, thanks!
When you creating tree object it doesn't creating any node. It's just defining a root variable with None. Node is creating when you call tree.insert() method.
insert() method in Tree class is checking if root is None it creating a new Node. Otherwise it calling the insert method in Node class.
Why does he made instance for tree not for node ?
Because insert() method in Node class only handles the case where tree has atleast one node or tree is not empty. That's why he creating the instance of Tree.
Code with insert() method in Tree class:
class Node():
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
class Tree():
def __init__(self):
self.root = None
def insert(self, root, data):
if root is None:
self.root = Node(data)
elif root.data < data:
if root.rightChild is None:
root.rightChild = Node(data)
else:
self.insert(root.rightChild, data)
else:
if root.leftChild is None:
root.leftChild = Node(data)
else:
self.insert(root.leftChild, data)

In a Python LinkedList, why use sentinel nodes instead of a None or Null

What is the difference between these constructors for a LinkedList, why is one better or worse than the other?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Singly_Linked_List:
def __init__(self):
self.head = None
versus:
class Singly_Linked_List:
def __init__(self):
self.head = Node(0)
Does this affect how the SLL or DLL would be implemented for the addAtIndex, removeAtIndex functions for example?

AttributeError: "instance has no attribute"

I am having a problem understanding why my code gives me this error
AttributeError: "Tree instance has no attribute 'root'"
I am trying to implement a binary search tree and here is my code.
class Node:
def __init__(self, value):
self.val = value
self.right = None
self.left = None
class Tree:
def __init__(self, val):
root = Node(val)
def main():
tree = Tree(100);
print tree.root.val
if __name__ == "__main__":
main()
I am new to python. Please let me know what is wrong with my code.
You should use self.root to tell the interpreter that the Tree class has a instance var named root.
class Tree:
def __init__(self, val):
self.root = Node(val)

Categories

Resources