I'm trying to do a search function for an AVL-tree, when i try to search for a number that is in the tree the code works fine, but i'm getting the error
AttributeError: 'NoneType' object has no attribute 'search'
when a try to search for a number that isn't in the tree
This is the search function
def search(self, data):
if self is None:
return "the key doesn't exist"
elif data < self.data:
return self.left.busca(data)
elif data > self.data:
return self.right.busca(data)
else:
return "the key exist"
and the whole code(the name of the variables are in pt-br)
class No:
def __init__(self, data):
self.data = data
self.setaFilhos(None, None)
def setaFilhos(self, esquerda, direita):
self.esquerda = esquerda
self.direita = direita
def balanco(self):
prof_esq = 0
if self.esquerda:
prof_esq = self.esquerda.profundidade()
prof_dir = 0
if self.direita:
prof_dir = self.direita.profundidade()
return prof_esq - prof_dir
def profundidade(self):
prof_esq = 0
if self.esquerda:
prof_esq = self.esquerda.profundidade()
prof_dir = 0
if self.direita:
prof_dir = self.direita.profundidade()
return 1 + max(prof_esq, prof_dir)
def rotacaoEsquerda(self):
self.data, self.direita.data = self.direita.data, self.data
old_esquerda = self.esquerda
self.setaFilhos(self.direita, self.direita.direita)
self.esquerda.setaFilhos(old_esquerda, self.esquerda.esquerda)
def rotacaoDireita(self):
self.data, self.esquerda.data = self.esquerda.data, self.data
old_direita = self.direita
self.setaFilhos(self.esquerda.esquerda, self.esquerda)
self.direita.setaFilhos(self.direita.direita, old_direita)
def rotacaoEsquerdaDireita(self):
self.esquerda.rotacaoEsquerda()
self.rotacaoDireita()
def rotacaoDireitaEsquerda(self):
self.direita.rotacaoDireita()
self.rotacaoEsquerda()
def executaBalanco(self):
bal = self.balanco()
if bal > 1:
if self.esquerda.balanco() > 0:
self.rotacaoDireita()
else:
self.rotacaoEsquerdaDireita()
elif bal < -1:
if self.direita.balanco() < 0:
self.rotacaoEsquerda()
else:
self.rotacaoDireitaEsquerda()
def insere(self, data):
if data <= self.data:
if not self.esquerda:
self.esquerda = No(data)
else:
self.esquerda.insere(data)
else:
if not self.direita:
self.direita = No(data)
else:
self.direita.insere(data)
self.executaBalanco()
def remove(self, data):
if self.direita is None and self.esquerda is None:
return None
if data < self.data:
self.esquerda = self.esquerda.remove(data)
elif data > self.data:
self.direita = self.direita.remove(data)
else:
if self.direita is None:
return self.esquerda
if self.esquerda is None:
return self.direita
tmp = self.direita._min()
self.data = tmp.data
self.direita = self.direita.remove(tmp.data)
self.executaBalanco()
return self
def busca(self, data):
if self is None:
return "A chave não existe"
elif data < self.data:
return self.esquerda.busca(data)
elif data > self.data:
return self.direita.busca(data)
else:
return "A chave existe"
def _min(self):
if self.esquerda is None:
return self
else:
return self.esquerda._min()
def imprimeArvore(self, indent = 0):
print ( "-" * indent + "|" + str(self.data))
if self.esquerda:
self.esquerda.imprimeArvore(indent + 2)
if self.direita:
self.direita.imprimeArvore(indent + 2)
arvore = None
for data in [15, 27, 49, 10, 8, 67, 59, 9, 13, 20, 14]:
if arvore:
arvore.insere(data)
else:
arvore = No(data)
arvore.imprimeArvore()
arvore.busca(1)
I think the problem is the returning when the key is not found, but i not sure, none of the similar question that i tried to read helped me and i tried to look the code of other people and at least for me my code should work . What did i do wrong?There is another way to do it?
def search(self, data):
if self is None:
return "the key doesn't exist"
elif data < self.data:
return self.left.busca(data)
elif data > self.data:
return self.right.busca(data)
else:
return "the key exist"
If the search method is called successfully, self is not None.
You should check whether self.left is None or self.right is None before making the recursive call to search.
def search(self, data):
if data == self.data:
return "the key exists"
if data < self.data and self.left is not None:
return self.left.busca(data)
elif data > self.data and self.right is not None:
return self.right.busca(data)
else:
return "the key exist"
Related
Got a task: to implement a dictionary based on a search tree with B-balancing, in which the data is stored in leaves.
I wrote a dictionary class: B-balanced segment tree. I understand that a search tree with keys k1, k2, k3 ... kn corresponds to a segment tree with segments, or rather, half-intervals (-inf,k1) [k1, k2) [k2, k3) ... [kn, inf) , but I don't understand how to implement it in terms of my class. I would really appreciate any help.
class Node:
def __init__(self, segment,value = None,children = []):
self.segment = segment
self.value = value
self.children = children
self.exist = 1
class Dict():
def __init__(self):
self.root = None
self.len = 0
self.t = 4
self.combine = sum
def __len__(self):
return self.len
def __getitem__(self, key):
if not self.root:
raise KeyError()
else:
return self.get(self.root, key)
def __contains__(self, key):
try:
self.__getitem__(key)
return True
except:
return False
def __setitem__(self, key, value):
if not self.root:
self.root = self.make_branch([self.make_leaf(key,value)])
self.len += 1
else:
if key not in self:
self.len += 1
self.root = self.tree_put(self.root, key, value)
def __delitem__(self, key):
if key not in self:
raise KeyError()
else:
self.delete(self.root, key)
self.len -= 1
def get(self,tree,key):
if key == tree.segment[0] and key == tree.segment[1] and tree.exist == 1:
return tree.value
elif tree.segment[0] != tree.segment[1]:
i = 0
while i < len(tree.children):
if tree.children[i].segment[0] > key: break
i+=1
try:
return self.get(tree.children[i-1],key)
except:
raise KeyError()
raise KeyError()
def delete(self, tree, key):
if key == tree.segment[0] and key == tree.segment[1] and tree.exist == 1:
tree.exist = 0
return
elif tree.segment[0] != tree.segment[1]:
i = 0
if len(tree.children) > 0:
while i < len(tree.children):
if tree.children[i].segment[0] >= key: break
i+=1
try:
return self.delete(tree.children[i],key)
except:
return self.delete(tree.children[i-1],key)
raise KeyError()
def make_leaf(self, key, value): return Node((key, key), self.combine([value]), [] )
def make_branch(self, trees):
segments = [ tree.segment for tree in trees ]
left = segments[0][0]
right = segments[-1][1]
value = self.combine([ tree.value for tree in trees ])
return Node((left, right), value, trees[:])
def tree_segment_value(self, tree, a, b):
ta, tb = tree.segment
if a <= ta and tb <= b: return tree.value
to_combine = []
for child in tree.children:
ta, tb = child.segment
if tb < a: continue
if ta > b: break
if a <= ta and tb <= b: to_combine.append(child.value)
else: to_combine.append(tree_segment_value(child, a, b))
return self.combine(to_combine)
def tree_put_rec(self,tree,key,value):
if tree == None:
return [self.make_branch([self.make_leaf(key,value)])]
i = 0
while i < len(tree.children):
if tree.children[i].segment[0] > key: break
i+=1
if i > 0: i-=1
left_children = tree.children[:i]
right_children = tree.children[i+1:]
child = tree.children[i]
if len(child.children) == 0:
new_leaf = self.make_leaf(key,value)
child_key = child.segment[0]
if child_key < key: mid_children = [child,new_leaf]
elif child_key > key: mid_children = [new_leaf,child]
else: mid_children = [new_leaf]
else:
mid_children = self.tree_put_rec(child,key,value)
new_children = left_children+mid_children+right_children
N = len(new_children)
if N > self.t: to_wrap = [new_children[:N//2],new_children[N//2:]]
else: to_wrap = [new_children]
return [self.make_branch(subtrees) for subtrees in to_wrap]
def tree_put(self, tree,key,value):
new_trees = self.tree_put_rec(tree,key,value)
if len(new_trees) < 2: return new_trees[0]
return self.make_branch(new_trees)
Picture of Question with specific details
I'm trying to write a function that creates a binary search tree. Here's what I have so far:
def add_items(bst, low, high):
if low == high:
bst.insert(high)
return
else:
left = add_items(bst, low, high)
right = add_items(bst, low, high)
item = BinarySearchTreeMap.Item(low)
node = BinarySearchTreeMap.BinarySearchTreeMap.Node(item)
node.left = left
node.right = right
return node
The problems I noticed with this is that the function returns a node when it finishes all the recursive calls. I want to return the root of this binary search tree, but I'm not sure how to return it at the end. The picture includes a more detailed description of what I am trying to do. I appreciate any help, advice, or ideas anyone may have. add_items is actually sort of a helper function as it is called by this little snippet of code:
def create_complete_bst(n):
bst = BinarySearchTreeMap.BinarySearchTreeMap()
add_items(bst, 1, n)
return bst
P.S. here is the binary search tree class that I have been provided with and am using in this program
class BinarySearchTreeMap:
class Item:
def __init__(self, key, value=None):
self.key = key
self.value = value
class Node:
def __init__(self, item):
self.item = item
self.parent = None
self.left = None
self.right = None
def num_children(self):
count = 0
if (self.left is not None):
count += 1
if (self.right is not None):
count += 1
return count
def disconnect(self):
self.item = None
self.parent = None
self.left = None
self.right = None
def __init__(self):
self.root = None
self.size = 0
def __len__(self):
return self.size
def is_empty(self):
return len(self) == 0
# raises exception if not found
def __getitem__(self, key):
node = self.find(key)
if (node is None):
raise KeyError(str(key) + " not found")
else:
return node.item.value
# returns None if not found
def find(self, key):
curr = self.root
while (curr is not None):
if (curr.item.key == key):
return curr
elif (curr.item.key > key):
curr = curr.left
else: # (curr.item.key < key)
curr = curr.right
return None
# updates value if key already exists
def __setitem__(self, key, value):
node = self.find(key)
if (node is None):
self.insert(key, value)
else:
node.item.value = value
# assumes key not in tree
def insert(self, key, value=None):
item = BinarySearchTreeMap.Item(key, value)
new_node = BinarySearchTreeMap.Node(item)
if (self.is_empty()):
self.root = new_node
self.size = 1
else:
parent = self.root
if(key < self.root.item.key):
curr = self.root.left
else:
curr = self.root.right
while (curr is not None):
parent = curr
if (key < curr.item.key):
curr = curr.left
else:
curr = curr.right
if (key < parent.item.key):
parent.left = new_node
else:
parent.right = new_node
new_node.parent = parent
self.size += 1
# raises exception if key not in tree
def __delitem__(self, key):
node = self.find(key)
if (node is None):
raise KeyError(str(key) + " is not found")
else:
self.delete_node(node)
# assumes key is in tree + returns value assosiated
def delete_node(self, node_to_delete):
item = node_to_delete.item
num_children = node_to_delete.num_children()
if (node_to_delete is self.root):
if (num_children == 0):
self.root = None
node_to_delete.disconnect()
self.size -= 1
elif (num_children == 1):
if (self.root.left is not None):
self.root = self.root.left
else:
self.root = self.root.right
self.root.parent = None
node_to_delete.disconnect()
self.size -= 1
else: #num_children == 2
max_of_left = self.subtree_max(node_to_delete.left)
node_to_delete.item = max_of_left.item
self.delete_node(max_of_left)
else:
if (num_children == 0):
parent = node_to_delete.parent
if (node_to_delete is parent.left):
parent.left = None
else:
parent.right = None
node_to_delete.disconnect()
self.size -= 1
elif (num_children == 1):
parent = node_to_delete.parent
if(node_to_delete.left is not None):
child = node_to_delete.left
else:
child = node_to_delete.right
child.parent = parent
if (node_to_delete is parent.left):
parent.left = child
else:
parent.right = child
node_to_delete.disconnect()
self.size -= 1
else: #num_children == 2
max_of_left = self.subtree_max(node_to_delete.left)
node_to_delete.item = max_of_left.item
self.delete_node(max_of_left)
return item
# assumes non empty subtree
def subtree_max(self, curr_root):
node = curr_root
while (node.right is not None):
node = node.right
return node
def inorder(self):
for node in self.subtree_inorder(self.root):
yield node
def subtree_inorder(self, curr_root):
if(curr_root is None):
pass
else:
yield from self.subtree_inorder(curr_root.left)
yield curr_root
yield from self.subtree_inorder(curr_root.right)
def __iter__(self):
for node in self.inorder():
yield node.item.key
After revising with suggestions:
def create_complete_bst(n):
bst = BinarySearchTreeMap.BinarySearchTreeMap()
add_items(bst, 1, n)
return bst
def add_items(bst, low, high):
if low == high:
bst.insert(high)
return
elif high < low:
return
else:
mid = (low+high) // 2
bst.insert(mid)
add_items(bst, low, mid-1)
add_items(bst, mid+1, high)
return bst
Sorry for all of the code, but for this assignment I am working on, it is necessary due to different references.
This chapter we are working with Binary Trees and Binary Search Trees.
I tested the BinaryTree() and BinarySearchTree() classes with no issue.
My problem is this: we are adding records to a binary search tree as seen in the Student class and the main() function to test the class. According to the assignment:
The Student class has an id and name, getters and setters, a str() function so that you can print a student record, and the operations ==, !=, <=, <, >=, > defined. The comparison operators compare student id's which are intended to be unique. Since we can compare student records, we can now put them into a Binary Search Tree.
My question is, how do I add the records a binary tree if all of the initialized variables are completely different than ones in the BinaryTree() class and the BinarySearchTree() class?
Everytime I run the code, I get errors such as:
AttributeError: 'Student' object has no attribute 'insert'
or
isEmpty() = True
None
isEmpty() = False
None
101(Betty Smith)
101(Betty Smith)
Traceback (most recent call last):
File "/Users/phillipward/Desktop/Lab 10/StudentRecordsTest.py", line 50, in <module>
main()
File "/Users/phillipward/Desktop/Lab 10/StudentRecordsTest.py", line 22, in main
BST.insert(Student(42, "Amy Winchester"))
File "/Users/phillipward/Desktop/Lab 10/BinarySearchTree.py", line 13, in insert
self.getleftChild().insert(data)
File "/Users/phillipward/Desktop/Lab 10/BinarySearchTree.py", line 7, in insert
if(self.isEmpty()):
File "/Users/phillipward/Desktop/Lab 10/binaryTree.py", line 33, in isEmpty
if(self is None or self.data is None):
AttributeError: 'Student' object has no attribute 'data'
I'm stuck on how to tell the program that I the student class is a type of BinarySearchTree.
class BinaryTree():
def __init__(self, data = None, leftChild = None, rightChild = None):
self.data = data
self.leftChild = leftChild
self.rightChild = rightChild
def getData(self):
return self.data
def setData(self, x):
self.data = x
return self.data
def getleftChild(self):
return self.leftChild
def setleftChild(self, x):
self.leftChild = x
return self.leftChild
def getrightChild(self):
return self.rightChild
def setrightChild(self, x):
self.rightChild = x
return self.rightChild
def isEmpty(self):
if(self is None or self.data is None):
return True
else:
return False
def __str__ (self):
return "{0}".format(self.data)
def inOrderTraversal(self):
if (self is None):
return "Empty"
else:
result = ""
if(self.getleftChild() is not None): # When we put payload in, we need equality
result += BinaryTree.inOrderTraversal(self.getleftChild()) + " "
result += str(self.getData())
if (self.getrightChild() is not None):
result += " " + BinaryTree.inOrderTraversal(self.getrightChild()) + " "
return result
def preOrderTraversal(self):
if (self.isEmpty()):
return "Empty"
else:
result = ""
result += str(self.getData())
if (self.getleftChild() is not None):
result += " " + BinaryTree.preOrderTraversal(self.getleftChild()) + " "
if (self.getrightChild() is not None):
result += BinaryTree.preOrderTraversal(self.getrightChild())
return result
def postOrderTraversal(self):
if (self.isEmpty()):
return "Empty"
else:
result = ""
if (self.getleftChild() is not None):
result += BinaryTree.postOrderTraversal(self.getleftChild()) + " "
if (self.getrightChild() is not None):
result += BinaryTree.postOrderTraversal(self.getrightChild()) + " "
result += str(self.getData())
return result
def insert(self, data):
if (self.isEmpty()):
self.setData(data)
elif (data < self.getData()):
if (self.getleftChild() is None):
self.setleftChild(BinarySearchTree(data))
else:
self.getleftChild().insert(data)
else: # data >= self.getData()
if (self.getrightChild() is None):
self.setrightChild(BinarySearchTree(data))
else:
self.getrightChild().insert(data)
def retrieve(self, data):
if self.isEmpty():
return None
elif data == self.getData():
return self.getData()
elif data <= self.getData():
if self.getleftChild() is None:
return None
else:
return self.getleftChild().retrieve(data)
else:
if self.getrightChild() is None:
return None
else:
return self.getrightChild().retrieve(data)
from binaryTree import BinaryTree
class BinarySearchTree(BinaryTree):
def insert(self, data):
if(self.isEmpty()):
self.setData(data)
elif(data < self.getData()):
if(self.getleftChild() is None):
self.setleftChild(data)
else:
self.getleftChild().insert(data)
else: #data >= self.getData()
if(self.getrightChild() is None):
self.setrightChild(data)
else:
self.getrightChild().insert(data)
def retrieve(self, data):
if self.isEmpty():
return None
elif data == self.getData():
return self.getData()
elif data <= self.getData():
if self.getleftChild() is None:
return None
else:
return self.getleftChild().retrieve(data)
else:
if self.getrightChild() is None:
return None
else:
return self.getrightChild().retrieve(data)
def minValue(self):
current = self
while current.leftChild is not None:
current = current.leftChild
return current.data
def maxValue(self):
current = self
while current.rightChild is not None:
current = current.rightChild
return current.data
def isBST(self):
current = self
if current == None:
return True
if current.leftChild.data <= current.data and
current.rightChild.data >= current.data:
return True
else:
return False
class Student():
def __init__(self, id = None, name = ""):
self.__id = id
self.__name = name
def getId(self):
return self.__id
def setId(self, id):
self.__id = id
def getName(self):
return self.__name
def setName(self, name):
self.__id = name
def __str__(self):
if (self is None):
return ""
else:
return str(self.__id) + "(" + self.__name + ")"
def __cmp__(self, other):
if (self is None or other is None):
return 0
else:
return self.__id - other.__id
def __eq__(self, other):
return self.__cmp__(other) == 0
def __ne__(self, other):
return self.__cmp__(other) != 0
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
from BinarySearchTree import BinarySearchTree
from Student import Student
def main():
BST = BinarySearchTree()
print("isEmpty() = " + str(BST.isEmpty()))
print(BST)
BST.setData(Student(101, "Betty Smith"))
print("isEmpty() = " + str(BST.isEmpty()))
print(BinarySearchTree())
BST.insert(Student(50, "John Adams"))
print(BST)
BST.insert(Student(250, "Mike Jones"))
print(BST)
BST.insert(Student(42, "Amy Winchester"))
print(BST)
BST.insert(Student(31, "Jill Ranger"))
print(BST)
BST.insert(Student(315, "Bob Crachet"))
print(BST)
BST.insert(Student(200, "Karen Wilkins"))
print(BST)
print("\n")
print()
print("Inorder traversal: " + str(BST))
print()
print("Preorder traversal: \n" + BST.preOrderTraversal())
print()
print("Postorder traversal: " + BST.postOrderTraversal())
print()
print("minValue: " + str(BST.minValue()))
print("maxValue: " + str(BST.maxValue()))
print()
print("isBST = " + str(BST.isBST()))
for id in [101, 200, 31, 50, 315, 250, 42]:
print(BST.retrieve(Student(id)))
main()
I am indexing a large CSV (5000+ lines) file into Python using the following code:
index = {}
df = open('file.csv', encoding='UTF-8')
fp = 0
l = df.readline()
while l:
r = l.split(',')
index[r[0]] = fp
fp = df.tell()
l = df.readline()
df.seek(index["Sarah"])
print(df.readline())
df.close()
Here is an example of the file content:
John, Always wears a blue hat
Alex, Always wears a red shirt
Sarah, Hates the colour pink
Here is an example of how they have been indexed:
{'John': 26389, 'Alex': 217059, 'Sarah': 142108...}
I am trying to add the indexed data into a binary search tree I've built using a tutorial on interactivepython. Here is the BST:
class TreeNode:
def __init__(self,key,val,left=None,right=None,parent=None):
self.key = key
self.payload = val
self.leftChild = left
self.rightChild = right
self.parent = parent
def hasLeftChild(self):
return self.leftChild
def hasRightChild(self):
return self.rightChild
def isLeftChild(self):
return self.parent and self.parent.leftChild == self
def isRightChild(self):
return self.parent and self.parent.rightChild == self
def isRoot(self):
return not self.parent
def isLeaf(self):
return not (self.rightChild or self.leftChild)
def hasAnyChildren(self):
return self.rightChild or self.leftChild
def hasBothChildren(self):
return self.rightChild and self.leftChild
def replaceNodeData(self,key,value,lc,rc):
self.key = key
self.payload = value
self.leftChild = lc
self.rightChild = rc
if self.hasLeftChild():
self.leftChild.parent = self
if self.hasRightChild():
self.rightChild.parent = self
class BinarySearchTree:
def __init__(self):
self.root = None
self.size = 0
def length(self):
return self.size
def __len__(self):
return self.size
def put(self,key,val):
if self.root:
self._put(key,val,self.root)
else:
self.root = TreeNode(key,val)
self.size = self.size + 1
def _put(self,key,val,currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key,val,currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key,val,parent=currentNode)
else:
if currentNode.hasRightChild():
self._put(key,val,currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key,val,parent=currentNode)
def __setitem__(self,k,v):
self.put(k,v)
def get(self,key):
if self.root:
res = self._get(key,self.root)
if res:
return res.payload
else:
return None
else:
return None
def _get(self,key,currentNode):
if not currentNode:
return None
elif currentNode.key == key:
return currentNode
elif key < currentNode.key:
return self._get(key,currentNode.leftChild)
else:
return self._get(key,currentNode.rightChild)
def __getitem__(self,key):
return self.get(key)
def __contains__(self,key):
if self._get(key,self.root):
return True
else:
return False
def delete(self,key):
if self.size > 1:
nodeToRemove = self._get(key,self.root)
if nodeToRemove:
self.remove(nodeToRemove)
self.size = self.size-1
else:
raise KeyError('Error, key not in tree')
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = self.size - 1
else:
raise KeyError('Error, key not in tree')
def __delitem__(self,key):
self.delete(key)
def spliceOut(self):
if self.isLeaf():
if self.isLeftChild():
self.parent.leftChild = None
else:
self.parent.rightChild = None
elif self.hasAnyChildren():
if self.hasLeftChild():
if self.isLeftChild():
self.parent.leftChild = self.leftChild
else:
self.parent.rightChild = self.leftChild
self.leftChild.parent = self.parent
else:
if self.isLeftChild():
self.parent.leftChild = self.rightChild
else:
self.parent.rightChild = self.rightChild
self.rightChild.parent = self.parent
def findSuccessor(self):
succ = None
if self.hasRightChild():
succ = self.rightChild.findMin()
else:
if self.parent:
if self.isLeftChild():
succ = self.parent
else:
self.parent.rightChild = None
succ = self.parent.findSuccessor()
self.parent.rightChild = self
return succ
def findMin(self):
current = self
while current.hasLeftChild():
current = current.leftChild
return current
def remove(self,currentNode):
if currentNode.isLeaf(): #leaf
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
else:
currentNode.parent.rightChild = None
elif currentNode.hasBothChildren(): #interior
succ = currentNode.findSuccessor()
succ.spliceOut()
currentNode.key = succ.key
currentNode.payload = succ.payload
else: # this node has one child
if currentNode.hasLeftChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
elif currentNode.isRightChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
else:
if currentNode.isLeftChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.rightChild
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.rightChild
else:
currentNode.replaceNodeData(currentNode.rightChild.key,
currentNode.rightChild.payload,
currentNode.rightChild.leftChild,
currentNode.rightChild.rightChild)
I can add individual items using the command:
mytree = BinarySearchTree()
mytree[1] = "One"
What I am trying to do is iterate over the index dictionary but I keep getting an error.
Here is how I am iterating over the dictionary:
for k, v in index.items():
mytree[k] = v
I think what you mean to do is to add the elements in the binary tree based on their csv position. If so, then try adding the element based on their value (instead of the key).
for k, v in index.items():
mytree[v] = k
EDIT: Based on the comments, it looks like the OP is trying to enter the elements in the tree based on their names (and not values). In order to catch which key value pair is causing this exception, how about adding this code? This would atleast narrow down the issue to the specific key-value pair causing this exception. One possibility is that the key in some cases is a string and in other cases might be a int (just a guess!)
def _put(self,key,val,currentNode):
try:
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key,val,currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key,val,parent=currentNode)
else:
if currentNode.hasRightChild():
self._put(key,val,currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key,val,parent=currentNode)
except TypeError as e:
print "key = ", key
print "currentNode key = ", currentNode.key
print "val = ", val
raise e
You get the error as soon as some of the keys are ints and some are strings, they aren't comparable so that's not going to work.
Did you actually use the line
ytree[1] = "One"
? Because that uses an int key, and the rest of the code inserts strings as keys. It should have been the other way around.
How can I fix the delete method so that it can also delete the head node?
class LinkedListNode():
def __init__(self, data=None, next_node=None):
self.data = data
self.next_node = next_node
def data(self):
return self.data
def next_node(self):
return self.next_node
def set_next_node(self, next_node):
self.next_node = next_node
def search(self, data):
index = 0
while self.next_node != None and self != None:
if self.data == data:
return index
else:
self = self.next_node
index += 1
return -1
def delete(self, data):
head = self
if self.data == data:
head = self.next_node
while self.next_node != None and self != None:
if self.next_node.data == data:
if self.next_node.next_node != None:
self.next_node = self.next_node.next_node
else:
self.next_node = None
else:
self = self.next_node
return head
def print(self):
while self.next_node != None:
print("%s: %s" % ("current node data is", self.data))
self = self.next_node
if self.next_node == None and self != None:
print("%s: %s" % ("current node data is", self.data))
and in the test file I have:
from LinkedListNode import *
head = LinkedListNode(3)
node1 = LinkedListNode('cat')
node2 = LinkedListNode('dog')
node3 = LinkedListNode(4)
head.set_next_node(node1)
node1.set_next_node(node2)
node2.set_next_node(node3)
print(head.search('dog'))
head.delete(3)
head.delete(4)
head.print()
I get:
2
current node data is: 3
current node data is: cat
current node data is: dog
Process finished with exit code 0
First of all, I believe that you are not supposed to reassign the 'self' in search method:
def search(self, data):
index = 0
while self.next_node != None and self != None:
if self.data == data:
return index
else:
self = self.next_node
index += 1
return -1
Replace it with a simple recursive version and try again:
def search(self, data):
if self.data == data:
return 0
elif self.next_node == None:
return -1
else:
idx = self.next_node.search(data)
if idx == -1:
return -1
else:
return 1 + idx