cannot delete root node in a binary search tree - python

**deleting the root(the first node i enter strong text) node shows the error 'TreeNode' object has no attribute 'findSuccessor'
when i try to delete the first node that is inserted it shows an attribute eroor
but the nodes that are inserted later get delete
can you tell me what is wrong with code **
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)

Related

Trouble returning tuple in a recursive binary tree function

I am writing a function that recursively finds the minimum and maximum values in a binary tree and returns a tuple (min, max). My code is returning the correct min and max for my test case but separately. Any advice on how to get it to return a tuple is appreciated! (As a note, I am not allowed to use LinkedBinaryTree functions that iterate over the tree for me but I attached the class I am currently using under my code)
My code
from LinkedBinaryTree import LinkedBinaryTree
def min_and_max(bin_tree):
if bin_tree is None:
raise Exception("Tree is empty")
def subtree_min_and_max(root):
minval = root.data
maxval = root.data
if (root.left is None and root.right is None):
temp = (minval, maxval)
return temp
elif (root.left is None):
ltemp = subtree_min_and_max(root.right)
if (ltemp[0] < minval):
minval= ltemp[0]
if (ltemp[1] > maxval):
maxval = ltemp[1]
temp = (minval, maxval)
return temp
elif (root.right is None):
subtree_min_and_max(root.left)
rtemp = subtree_min_and_max(root.right)
if (rtemp[0] < minval):
minval = rtemp[0]
if (rtemp[1] > maxval):
maxval = rtemp[1]
temp = (minval, maxval)
return temp
else:
ltemp = subtree_min_and_max(root.left)
rtemp = subtree_min_and_max(root.right)
print((min(root.data, ltemp[0], rtemp[0])))
print(max(root.data, ltemp[1], rtemp[1]))
temp = (min(root.data, ltemp[0], rtemp[0]), max(root.data, ltemp[1], rtemp[1]))
return temp
return subtree_min_and_max(bin_tree.root)
LinkedBinaryTree class
from ArrayQueue import ArrayQueue
class LinkedBinaryTree:
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
def __init__(self, root=None):
self.root = root
self.size = self.count_nodes()
def __len__(self):
return self.size
def is_empty(self):
return len(self) == 0
def count_nodes(self):
def subtree_count(root):
if (root is None):
return 0
else:
left_count = subtree_count(root.left)
right_count = subtree_count(root.right)
return 1 + left_count + right_count
return subtree_count(self.root)
def sum(self):
def subtree_sum(root):
if (root is None):
return 0
else:
left_sum = subtree_sum(root.left)
right_sum = subtree_sum(root.right)
return root.data + left_sum + right_sum
return subtree_sum(self.root)
def height(self):
def subtree_height(root):
if (root.left is None and root.right is None):
return 0
elif (root.left is None):
return 1 + subtree_height(root.right)
elif (root.right is None):
return 1 + subtree_height(root.left)
else:
left_height = subtree_height(root.left)
right_height = subtree_height(root.right)
return 1 + max(left_height, right_height)
if(self.is_empty()):
raise Exception("Tree is empty")
return subtree_height(self.root)
def preorder(self):
def subtree_preorder(root):
if (root is None):
pass
else:
yield root
yield from subtree_preorder(root.left)
yield from subtree_preorder(root.right)
yield from subtree_preorder(self.root)
def postorder(self):
def subtree_postorder(root):
if (root is None):
pass
else:
yield from subtree_postorder(root.left)
yield from subtree_postorder(root.right)
yield root
yield from subtree_postorder(self.root)
def inorder(self):
def subtree_inorder(root):
if (root is None):
pass
else:
yield from subtree_inorder(root.left)
yield root
yield from subtree_inorder(root.right)
yield from subtree_inorder(self.root)
def breadth_first(self):
if (self.is_empty()):
return
line = ArrayQueue()
line.enqueue(self.root)
while (line.is_empty() == False):
curr_node = line.dequeue()
yield curr_node
if (curr_node.left is not None):
line.enqueue(curr_node.left)
if (curr_node.right is not None):
line.enqueue(curr_node.right)
def __iter__(self):
for node in self.breadth_first():
yield node.data
My tester code
root = LinkedBinaryTree.Node(3)
T = LinkedBinaryTree(root)
a = LinkedBinaryTree.Node(2)
a.parent = root
root.left = a
b = LinkedBinaryTree.Node(7)
b.parent = root
root.right = b
c = LinkedBinaryTree.Node(9)
c.parent = a
a.left = c
d = LinkedBinaryTree.Node(5)
d.parent = c
c.left = d
e = LinkedBinaryTree.Node(1)
e.parent = c
c.right = e
f = LinkedBinaryTree.Node(8)
f.parent = b
b.left = f
g = LinkedBinaryTree.Node(4)
g.parent = b
b.right = g
print(min_and_max(T))
The tester code makes a tree that looks like
In subtree_min_and_max, when the case root.right is None, your code do:
subtree_min_and_max(root.left)
rtemp = subtree_min_and_max(root.right)
Which should be a single
rtemp = subtree_min_and_max(root.left)
as at this time, the sub-tree has empty right children, and the procedure should search for min and max in the left children.

Both AssertEqual and AssertNotEqual give failure in my unittest in Python

I have this test code on Binary Tree:
def test_deleteMin_root(self):
btree = BinaryTree()
min_value = self.person('AAKVIK', 'ANNE-MARIT', 'RISØYVEGEN 17', '1705', 'SARPSBORG')
node = BinaryTreeNode(min_value)
btree.insert(value = min_value)
btree.insert(value = self.person('Zero', 'Zero', 'Zero street', '1234', 'ZeroCity'))
btree.deleteMin()
self.assertEqual(node, btree.findMin())
I get this failure result:
======================================================================
FAIL: test_deleteMin_root (__main__.BinaryTreeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\abdka\Documents\Programs\Python\PythonExercises\aicourse\test_binarytree.py", line 47, in test_deleteMin_root
self.assertEqual(node, btree.findMin())
AssertionError: <BinaryTreeNode.BinaryTreeNode object at 0x000001C7E33EFA00> != <BinaryTreeNode.BinaryTreeNode object at 0x000001C7EAB5A6D0>
When I change AssertEqual to AssertNotEqual in the last line of the test code (and that's the only thing I change):
def test_deleteMin_root(self):
btree = BinaryTree()
min_value = self.person('AAKVIK', 'ANNE-MARIT', 'RISØYVEGEN 17', '1705', 'SARPSBORG')
node = BinaryTreeNode(min_value)
btree.insert(value = min_value)
btree.insert(value = self.person('Zero', 'Zero', 'Zero street', '1234', 'ZeroCity'))
btree.deleteMin()
self.assertNotEqual(node, btree.findMin())
I get this failure:
======================================================================
FAIL: test_deleteMin_root (__main__.BinaryTreeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\abdka\Documents\Programs\Python\PythonExercises\aicourse\test_binarytree.py", line 47, in test_deleteMin_root
self.assertNotEqual(node, btree.findMin())
AssertionError: <BinaryTreeNode.BinaryTreeNode object at 0x000001C7EE3D4F10> == <BinaryTreeNode.BinaryTreeNode object at 0x000001C7E5DCAA00>
When I assert equal, it says they're not equal, and when I assert not equal, it says they're equal. I don't understand; what's the error here? How can I fix it?
Here's the full test code, BinaryTree code and BinaryTreeNode code:
Binary Tree code:
from BinaryTreeNode import BinaryTreeNode
class BinaryTree:
def __init__(self, data = None):
self._root = None
if isinstance(data, BinaryTreeNode):
self._root = data
def findLeftMost(self, treenode):
left = treenode.left
if left == None:
return treenode
return self.findLeftMost(left)
def findMin(self):
return self.findLeftMost(self._root)
def findRightMost(self, treenode):
right = treenode.right
if right == None:
return treenode
return self.findRightMost(right)
def findMax(self):
return self.findRightMost(self._root)
def find(self, key, treenode = None):
if treenode == None:
treenode = self._root
if treenode == None:
return None
elif treenode.value > key:
if treenode.left:
return self.find(key, treenode.left)
elif treenode.value < key:
if treenode.right:
return self.find(key, treenode.right)
elif treenode.value == key:
return treenode
else:
raise KeyError("Key not found")
def _getnodes(self, current = None, treenode = None, value = None):
if current != None and treenode != None:
return current, treenode
if value == None:
if treenode == None:
raise Exception("Attempt to insert an empty space into Binary Tree")
else:
if treenode.value == None:
raise Exception("Attempt to insert an Node into Binary Tree with no key value")
else:
if treenode != None:
if treenode.value != None:
raise Exception("Key inconsistency detected")
else:
treenode = BinaryTreeNode(value)
if current == None:
current = self._root
return current, treenode
def insert(self, current = None, treenode = None, value = None):
if current == None:
current = self._root
# Checking consistency ...
current, treenode = self._getnodes(current, treenode, value)
if current != None:
if treenode.value < current.value:
treenode.level += 1
if current.left is None:
current.left = treenode
else:
self.insert(current.left, treenode)
elif treenode.value > current.value:
treenode.level += 1
if current.right is None:
current.right = treenode
else:
self.insert(current.right, treenode)
else:
if self._root == None:
treenode.level = 0
self._root = treenode
else:
raise Exception("Duplicate key: " + treenode.value)
else: # If empty tree, the first node entered is the root
self._root = treenode
return treenode
def deleteMin(self):
parent = self._root
while True:
# If a left branch exists - find the smallest item
current = parent.left
if current:
if current.left == None:
if current.right != None:
parent.left = current.right
return current
else:
parent.left = None
return current
else:
parent = current
# If no left branch exists, the root item is the smallest in the tree
else:
self._root = parent.right
return self._root
def deleteMax(self):
parent = self._root
while True:
current = parent.right
if current.right == None:
if current.left != None:
parent.right = current.left
return current
else:
parent.right = None
return current
else:
parent = current
def delete(self, key):
node = self.find(key)
delnode = node
if not node.left and not node.right:
node = None
elif node.right:
temptree = BinaryTree(node.right)
mintempnode = temptree.deleteMin()
node.value = mintempnode.value
elif node.left:
node = node.left
return delnode
Binary Tree Node code:
class BinaryTreeNode:
def __init__(self, value,
lefttree = None,
righttree = None):
self.value = value
self.left = lefttree
self.right = righttree
self.level = 0
# Bruker setter/getters
#property
def value(self):
return self.__value
#value.setter
def value(self, value):
self.__value = value
#property
def left(self):
return self.__left
#left.setter
def left(self, lefttree):
self.__left = lefttree
#property
def right(self):
return self.__right
#right.setter
def right(self, righttree):
self.__right = righttree
#property
def level(self):
return self.__level
#level.setter
def level(self, level):
self.__level = level
def __str__(self):
return self.value
def hasRight(self):
if self.right == None:
return False
return True
#return self.right != None
def hasLeft(self):
if self.left == None:
return False
return True
#return self.left != None
def prefixOrder(self):
print(str(self.value), ' ')
if self.hasLeft():
self.left.prefixOrder()
if self.hasRight():
self.right.prefixOrder()
def infixOrder(self):
if self.hasLeft():
self.left.infixOrder()
print(str(self.value), ' ')
if self.hasRight():
self.right.infixOrder()
def postfixOrder(self):
if self.hasLeft():
self.left.postfixOrder()
if self.hasRight():
self.right.postfixOrder()
print(str(self.value), ' ')
def levelOrder(self):
from queue import SimpleQueue
FIFOQueue = SimpleQueue()
FIFOQueue.put(self)
self.levelOrderEntry(FIFOQueue)
while not FIFOQueue.empty():
node = FIFOQueue.get()
print(str(node.value), ' ')
def levelOrderEntry(self, queue):
if queue.empty():
return
node = queue.get()
print(str(node.value), ' ')
if node.hasLeft():
queue.put(node.left)
if node.hasRight():
queue.put(node.right)
if node.hasLeft() or node.hasRight:
self.levelOrderEntry(queue)
def __eq__(self, other):
if other != None:
return self.value == other.value
elif other == None and self.value == None:
return True
return False
def __ne__(self, other):
if other != None:
if self.value == None:
return False
else:
return not self.value != other.value
return True
def __lt__(self, other):
if other != None:
return self.value < other.value
elif other == None and self.value == None:
return False
return False
def __le__(self, other):
if other != None:
return self.value <= other.value
elif other == None and self.value == None:
return False
return False
def __gt__(self, other):
if other != None:
return self.value > other.value
elif other == None and self.value == None:
return False
return False
def __ge__(self, other):
if other != None:
return self.value >= other.value
elif other == None and self.value == None:
return False
return False
The full test code:
import unittest
from BinaryTree import BinaryTree
from BinaryTreeNode import BinaryTreeNode
from collections import namedtuple
class BinaryTreeTest(unittest.TestCase):
def setUp(self):
self.person = namedtuple('person', ['lastname', 'firstname', 'address',
'postalcode', 'city'])
persons_file = open("Personer-kort.dta", 'r')
content = persons_file.read()
content = content.splitlines()
self.binarytree = BinaryTree()
for p in content:
self.binarytree.insert(value = self.person(*p.split(';')))
persons_file.close()
def test_findMin(self):
min_value = self.person('AAKVIK', 'ANETTE', 'BAKLIEN 11', '1360', 'NESBRU')
node = BinaryTreeNode(min_value)
self.assertEqual(node, self.binarytree.findMin())
def test_findMax(self):
max_value = self.person('ØYFOSS', 'ØISTEIN', 'ORHEIM 76', '0367', 'OSLO')
node = BinaryTreeNode(max_value)
self.assertEqual(node, self.binarytree.findMax())
def test_deleteMin(self):
self.binarytree.deleteMin()
min_value = self.person('AAKVIK', 'ANNE-MARIT', 'RISØYVEGEN 17', '1705', 'SARPSBORG')
node = BinaryTreeNode(min_value)
self.assertEqual(node, self.binarytree.findMin())
def test_deleteMin_root(self):
btree = BinaryTree()
min_value = self.person('AAKVIK', 'ANNE-MARIT', 'RISØYVEGEN 17', '1705', 'SARPSBORG')
node = BinaryTreeNode(min_value)
btree.insert(value = min_value)
btree.insert(value = self.person('Zero', 'Zero', 'Zero street', '1234', 'ZeroCity'))
btree.deleteMin()
self.assertNotEqual(node, btree.findMin())
def test_deleteMax(self):
self.binarytree.deleteMax()
max_value = self.person('ØYFOSS', 'WERNER STENVOLD', 'KIRKVOLL 28', '5935', 'LAVIK')
node = BinaryTreeNode(max_value)
self.assertEqual(node, self.binarytree.findMax())
def test_find(self):
value = self.person('SKARSHAUG','ASBJØRN HARALD', 'ALAPMO 72', '7290', 'STØREN')
node = BinaryTreeNode(value)
self.assertEqual(node, self.binarytree.find(value))
def test_find_key_not_found(self):
value = self.person('BORIS','JOHNSON', 'SOME STREET 72', '1234', 'LONDON')
self.assertEqual(None, self.binarytree.find(value))
self.assertRaises(KeyError, self.binarytree.find, value)
def test_delete(self):
value = self.person('SKARSHAUG','ASBJØRN HARALD', 'ALAPMO 72', '7290', 'STØREN')
node = BinaryTreeNode(value)
self.assertEqual(node, self.binarytree.find(value))
self.binarytree.delete(value)
self.assertEqual(None, self.binarytree.find(value))
def test_insert_value(self):
value1 = self.person('WIKILUND','JOHAN', 'SVETUN 11', '8510', 'NARVIK')
node1 = BinaryTreeNode(value1)
value2 = self.person('ALFRED', 'POLLEN', 'gate 11', '1234', 'KONGSBERG')
node2 = BinaryTreeNode(value2)
self.binarytree.insert(value=value1)
self.binarytree.insert(value=value2)
self.assertEqual(node1, self.binarytree.find(value1))
self.assertEqual(node2, self.binarytree.find(value2))
def test_insert_node(self):
value1 = self.person('WIKILUND','JOHAN', 'SVETUN 11', '8510', 'NARVIK')
node1 = BinaryTreeNode(value1)
value2 = self.person('ALFRED', 'POLLEN', 'gate 11', '1234', 'KONGSBERG')
node2 = BinaryTreeNode(value2)
self.binarytree.insert(treenode=node1)
self.binarytree.insert(treenode=node2)
self.assertEqual(node1, self.binarytree.find(value1))
self.assertEqual(node2, self.binarytree.find(value2))
def test_insert_duplicate(self):
value = self.person('SKARSHAUG','ASBJØRN HARALD', 'ALAPMO 72', '7290', 'STØREN')
self.assertRaisesRegex(Exception, "Duplicate key", self.binarytree.insert, [None, None, value])
def test_insert_empty_space(self):
self.assertRaisesRegex(Exception, "Attempt to insert an empty space into Binary Tree",
self.binarytree.insert, [None, None, None])
def test_insert_empty_node(self):
node = BinaryTreeNode(None)
self.assertRaisesRegex(Exception, "Attempt to insert an Node into Binary Tree with no key value",
self.binarytree.insert, [None, node, None])
def test_find_in_empty_tree(self):
tree = BinaryTree()
value = self.person('SKARSHAUG','ASBJØRN HARALD', 'ALAPMO 72', '7290', 'STØREN')
self.assertEqual(None, tree.find(value))
if __name__ == '__main__':
import sys;sys.argv = ['', 'BinaryTreeTest']
unittest.main()

Returning 'self' from one class instance function to another different class instance function is set to None

'''
Simple map ADT implementation using BST
'''
#! /usr/bin/env python3
import os
class TreeNode:
def __init__(self, key, data, left, right, parent):
self.key = key
self.value = data
self.leftchild = left
self.rightchild = right
self.parent = parent
def insertnode(self, key, value):
if key <= self.key:
#left child
if self.leftchild is not None:
self.leftchild.insertnode(key, value)
else:
self.leftchild = TreeNode(key=key, data=value, left=None, right=None, parent=self)
else:
if self.rightchild is not None:
self.rightchild.insertnode(key, value)
else:
self.rightchild = TreeNode(key=key, data=value, left=None, right=None, parent=self)
def displaynode(self):
if self.key is not None:
print(self.key, ":", self.value)
if self.leftchild is not None:
self.leftchild.displaynode()
if self.rightchild is not None:
self.rightchild.displaynode()
def search(self, key):
if self is None:
return None
elif key == self.key:
return self
elif key < self.key:
self.leftchild.search(key)
else:
self.rightchild.search(key)
def deletekey(self, key):
keyNode = self.search(key)
print(keyNode)
if keyNode is None:
raise KeyError('Key not found in the tree.')
else:
if keyNode.leftchild is None and keyNode.rightchild is None:
keyNode = None
elif keyNode.leftchild is not None and keyNode.rightchild is not None:
if keyNode.parent is None:
self.root = keyNode.leftchild
else:
keyNode.rightchild.parent = keyNode.leftchild
keyNode.parent.leftchild = keyNode.leftchild
keyNode = None
elif keyNode.leftchild is not None:
keyNode.parent.leftchild = keyNode.leftchild
keyNode = None
elif keyNode.rightchild is not None:
keyNode.parent.leftchild = keyNode.rightchild
keyNode = None
return True
class binaryTree():
def __init__(self):
self.root = None
self.size = 0
def length(self):
return self.size
def __len__(self):
return self.size
def insert(self, key, value):
if self.root is None:
self.root = TreeNode(key=key, data=value, left=None, right=None, parent=self)
self.size = self.size + 1
else:
self.root.insertnode(key, value)
self.size = self.size + 1
def display(self):
if self.root is None:
return None
else:
#currentNode = self.root
self.root.displaynode()
def __setitem__(self, key, value):
self.root.insertnode(key, value)
self.size = self.size + 1
def __contains__(self, item):
if self.root.search(item) is not None:
return True
else:
return False
def find(self, key):
if self.root.search(key) is not None:
return True
else:
return False
def __delitem__(self, key):
if self.root.deletekey(key, self.root):
self.size = self.size - 1
if __name__ == "__main__":
tree = binaryTree()
tree.insert(100, 'a')
tree.insert(50, 'b')
tree.insert(200, 'c')
#tree.insert(25, 'd')
tree[25] = 'd'
print(tree.size)
tree.display()
if 50 in tree:
print(f'{50} found')
else:
print(f'{50} not found')
print(tree.find(50))
tr = TreeNode(key = 100, data='a', left=None, right=None parent=None)
print(tr.search(100))
#del tree[50]
#tree.display()
I am looking for key 50 in the tree by overriding the 'in' using contains and the key is there in the tree which and it returns 'self' object from the search method in the class TreeNode.
However, when its evaluated in the contains or find() in the binary tree class its always None. Not sure what Iam missing here.

Maximum recursion with large lists

I am making a binary tree with a very large list, almost 10000 objects. The issue is that I get a maximum recursion error due to the huge size. It happens specifically in the binarytree class where TreeNode is being called to create new objects. I am unsure how to implement this without recursion, as it seems to be the easiest way to implement the code.
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
Binary Tree:
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
It is fairly simple to convert your recursive methods to iterative ones, e.g.:
def get(self, key):
node = self.root
while node:
if node.key == key:
return node.payload
elif key < node.key:
node = node.leftChild
else:
node = node.rightChild
return None
def put(self, key, val):
if not self.root:
self.root = TreeNode(key, val)
else:
self._put(key, val, self.root)
self.size = self.size + 1
def _put(self, key, val, currentNode):
while True:
if key < currentNode.key:
if currentNode.hasLeftChild():
currentNode = currentNode.leftChild
else:
currentNode.leftChild = TreeNode(key, val, parent=currentNode)
break
else:
if currentNode.hasRightChild():
currentNode = currentNode.rightChild
else:
currentNode.rightChild = TreeNode(key, val, parent=currentNode)
break
This gets rid of any recursion (limits) and is just as readable.

I keep getting this error:RecursionError: maximum recursion depth exceeded while calling a Python object

I am trying to use BFS to search through a tree with three letter words and find the way in between a given start and end word and print the way in between. The printing is supposed to be done with a recursive function.
I keep getting this error:
RecursionError: maximum recursion depth exceeded while calling a Python object
and an infinite loop with the endword can anyone see whats wrong? (I copied my imported classes as well).
from array import array
class Node1:
#håller koll på värdena
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
if self.data.parent == None:
return None
else:
print(self.data.parent)
return str(self.data.parent)
def __str__(self):
return str(self.data.word)
class Queue:
def __init__(self):
self.first = None
self.last = None
def enqueue(self,x):
"""Stoppar in x sist i kön """
x = Node1(x)
if self.first == None: # Om kön är tom
self.first = self.last = x
else: # om kön inte är tom
self.last.next = x
self.last = x
def dequeue(self):
first = self.first
self.first = self.first.next
#if self.first == None:
# self.last=None
return first
def isEmpty(self):
if self.first == None:
xx = True
else:
xx = False
#print('I IsEmpty: Första elementet i listan:',self.first)
#print('I IsEmpty: Sista elementet i listan:',self.last)
return xx
def __str__(self):
node=self.first
node_strang = 'Efter trolleriet får man: '
while node != None:
node_strang += str(node)
node = node.next
return node_strang
class Node:
'''Nodklass med rekursiva metoder som anropas i Bintree-klassen'''
def __init__(self, word):
self.word = word
self.left = None
self.right = None
def insert(self, new_word):
if self.word == new_word:
return False
elif new_word < self.word:
if self.left:
return self.left.insert(new_word)
else:
self.left = Node(new_word)
return True
else:
if self.right:
return self.right.insert(new_word)
else:
self.right = Node(new_word)
return True
def find(self, new_word):
if self.word == new_word:
return True
elif new_word < self.word:
if self.left:
return self.left.find(new_word)
else:
return False
else:
if self.right:
return self.right.find(new_word)
else:
return False
def preorder(self):
if self:
print(self.word)
if self.left:
self.left.preorder()
if self.right:
self.right.preorder()
def postorder(self):
if self:
if self.left:
self.left.postorder()
if self.right:
self.right.postorder()
print(self.word)
def inorder(self):
if self:
if self.left:
self.left.inorder()
print(self.word)
if self.right:
self.right.inorder()
from linkedQFile import Queue,Node1
from bintreeFile import Node
import string
class Bintree:
def __init__(self):
self.root = None
def put(self, new_word):
if self.root:
return self.root.insert(new_word)
else:
self.root = Node(new_word)
return True
def __contains__(self, new_word):
if self.root:
return self.root.find(new_word)
else:
return False
class ParentNode:
def __init__(self, word, parent = None):
self.word = word
self.parent = parent
def maketree():
svenska = Bintree()
gamla = Bintree()
with open('word3.txt', 'r') as ordfil:
for rad in ordfil:
ord = rad.strip()
if ord in svenska:
gamla.put(ord)
svenska.put(ord)
ordfil.close()
return svenska,gamla
def writechain(kidzen, paronen):
if paronen is not None:
print(kidzen)
writechain(kidzen, paronen)
else:
pass
def countchain(barn_obj):
if barn_obj.parent==None:
return 0
else:
return 1+countchain(barn_obj.parent)
def makechildren(nod, q, gamla, svenska):
for i in range(3):
bokstavslista = list(nod.data.word)
alfabetslista = list(string.ascii_lowercase) + ['å', 'ä', 'ö']
for bokstav in alfabetslista:
bokstavslista[i] = bokstav
barn = ''.join(bokstavslista)
if barn in svenska:
barn_obj = ParentNode(barn, nod.data)
#print('parent to', barn, 'is', str(barn_obj.parent))
if barn not in gamla:
#print("i makechildren: barn = ", barn)
q.enqueue(barn_obj)
gamla.put(barn_obj.word)
def main():
(svenska,gamla) = maketree()
q=Queue()
start = input('Startord:')
slut = input('Slutord:')
startord= ParentNode(start, parent=None)
q.enqueue(startord)
while not q.isEmpty():
nod = q.dequeue()
makechildren(nod, q, gamla, svenska)
nod_for=nod.data
kidzen=nod_for.word
paronen=nod_for.parent
#print ('word =', kidzen)
#print ('parent =', paronen)
if q.isEmpty():
print('Det finns ingen väg till', slut)
break
elif kidzen==slut:
writechain(kidzen, paronen)
print('Det finns en väg till', slut)
break
main()
In your writechain function you are not walking a tree.
You keep recursively calling it with the same arguments. That will continue until you reach the recursion limit.

Categories