I expect to print out [6,5,10
instead I only get 10 :
class BST:
arr = []
def __init__(self):
self.height = 0
self.key = 0
self.left = None
self.right = None
def __str__(self):
return str(self.key)
def populate(self):
print("populating")
print(self.key)
if (self.left != None):
BST.arr = BST.arr + [self.left.populate()]
if (self.right != None):
BST.arr = BST.arr + [self.right.populate()]
return self.key
m1 = BST()
m1.key = 10
m2 = BST()
m2.key = 5
m1.left = m2
print(m1.left != None)
m3 = BST()
m3.key = 6
m2.left = m3
res = m1.populate()
print(res)
Here's a function that does in order traversal:
def inOrder(node, order):
if node is not None:
inOrder(node.left, order)
order.append(node.key)
inOrder(node.right, order)
You can write a wrapper function that does return a list and use it like this:
def inOrder(root):
order = []
inOrder(root, order)
return order
Edit: Or you can do that with one function like this:
def inOrder(node):
if node is None:
return []
return inOrder(node.left) + [node.key] + inOrder(node.right)
A workaround is to update your populate method:
class BST:
arr = []
def __init__(self):
self.height = 0
self.key = 0
self.left = None
self.right = None
def __str__(self):
return str(self.key)
def populate(self):
self.arr = []
temp = self
while temp.left != None or temp.right!=None:
self.arr.append(temp.key)
if temp.left!=None:
temp = temp.left
elif temp.right!=None:
temp = temp.right
if temp.left == None and temp.right==None:
self.arr.append(temp.key)
return self.arr
m1 = BST()
m1.key = 10
m2 = BST()
m2.key = 5
m1.left = m2
print(m1.left != None)
m3 = BST()
m3.key = 6
m2.left = m3
res = m1.populate()
print(res)
Output:
True
[10, 5, 6]
Related
I have made the BST in Python, but I have a problem with printing it. When I try to print it like this: tree.BSTinOrder(Node(4)), it prints only 4 and below "None".
Generally I'd expect it to be printed "fine" so it can somehow draw the tree or at least that I could see which node is connected with other.
If I want to print whole tree, should I do some kind of loop?
My code:
class Node:
def __init__(self,x):
self.key = x
self.left = None
self.right = None
self.p = None
class BST:
def __init__(self):
self.root = None
def BSTsearch(self,k):
x = self.root
while x!=None and x.key!=k:
if k<x.key:
x=x.left
else:
x=x.right
return x
def BSTinsert(self, z):
x = self.root
y = None
while x != None:
y=x
if z.key<x.key:
x=x.left
else:
x=x.right
z.p=y
if y==None:
self.root=z
else:
if z.key<y.key:
y.left=z
else:
y.right=z
def bstDelete(self, z):
if z.left == None and z.right == None:
if z == self.root:
self.root = None
else:
if z == z.p.left:
z.p.left = None
else:
z.p.right = None
elif z.left != None and z.right != None:
y = self.bstMinimum(z.right)
z.key = y.key
self.bstDelete(y)
else:
if z.left != None:
z.left.p=z.p
if z==self.root:
self.root=z.left
else:
if z==z.p.left:
z.p.left=z.left
else:
z.p.right=z.left
else:
z.right.p=z.p
if z==self.root:
self.root=z.right
else:
if z==z.p.left:
z.p.left=z.left
else:
z.p.right=z.left
def bstMinimum(self, x):
while x.left != None:
x = x.left
return x
def BSTinOrder(self, x):
if x == None: return
self.BSTinOrder(x.left)
print(x.key)
self.BSTinOrder(x.right)
tree = BST()
tree.BSTinsert(Node(5))
tree.BSTinsert(Node(3))
tree.BSTinsert(Node(7))
tree.BSTinsert(Node(2))
tree.BSTinsert(Node(4))
tree.BSTinsert(Node(9))
tree.BSTinsert(Node(8))
Try this:
class Node:
def __init__(self, x):
self.key = x
self.left = None
self.right = None
self.p = None
class BST:
def __init__(self):
self.root = None
def BSTsearch(self, k):
x = self.root
while x != None and x.key != k:
if k < x.key:
x = x.left
else:
x = x.right
return x
def BSTinsert(self, z):
x = self.root
y = None
while x != None:
y = x
if z.key < x.key:
x = x.left
else:
x = x.right
z.p = y
if y == None:
self.root = z
else:
if z.key < y.key:
y.left = z
else:
y.right = z
def bstDelete(self, z):
if z.left == None and z.right == None:
if z == self.root:
self.root = None
else:
if z == z.p.left:
z.p.left = None
else:
z.p.right = None
elif z.left != None and z.right != None:
y = self.bstMinimum(z.right)
z.key = y.key
self.bstDelete(y)
else:
if z.left != None:
z.left.p = z.p
if z == self.root:
self.root = z.left
else:
if z == z.p.left:
z.p.left = z.left
else:
z.p.right = z.left
else:
z.right.p = z.p
if z == self.root:
self.root = z.right
else:
if z == z.p.left:
z.p.left = z.left
else:
z.p.right = z.left
def bstMinimum(self, x):
while x.left != None:
x = x.left
return x
def BSTinOrder(self, x):
if x == None: return
self.BSTinOrder(x.left)
print(x.key)
self.BSTinOrder(x.right)
def bstGetRoot(self):
return self.root
tree = BST()
tree.BSTinsert(Node(5))
tree.BSTinsert(Node(3))
tree.BSTinsert(Node(7))
tree.BSTinsert(Node(2))
tree.BSTinsert(Node(4))
tree.BSTinsert(Node(9))
tree.BSTinsert(Node(8))
tree.BSTinOrder(tree.bstGetRoot())
Output:
2
3
4
5
7
8
9
I think you misunderstood how to traverse through a tree. You would need the root for that. Notice how I added a method to retrieve the tree's root, and then passed it to the inoder traversal funtion, which worked just fine.
i implement a linked list in Python for my student and particulary a simply version of the "reverse" method ...
This a version that works :
class SimpleList:
def __init__(self, *args):
if len(args) == 0:
self.__cell = None
elif len(args) == 2:
if isinstance(args[1], SimpleList):
self.__cell = (args[0], args[1])
else:
print("Erreur 2")
else:
print("Erreur 3")
def car(self):
if not self.isNull():
return self.__cell[0]
print("Erreur 4")
def cdr(self):
if not self.isNull():
return self.__cell[1]
print("Erreur 5")
def isNull(self):
return self.__cell == None
def __repr__(self):
if self.isNull():
return '()'
else:
return '(' + repr(self.car()) + ',' + repr(self.cdr()) + ')'
def nbrElement(self):
num = 0
tab = self
while not(tab.isNull()):
num = num+1
tab = tab.cdr()
return num
def reverse(self):
num=self.nbrElement()-1
pCourant = SimpleList(self.car(),SimpleList())
tab = self.cdr()
for i in range(0,num-1):
tabTmp = tab
tab = tab.cdr()
tabTmp.__cell = (tabTmp.car(),pCourant)
pCourant= tabTmp
self.__cell = neww = (tab.car(),pCourant)
and the code to execute :
slA = SimpleList(10,SimpleList(9,SimpleList(8,SimpleList(7,SimpleList(6,SimpleList(5,SimpleList(4,SimpleList())))))))
print(slA)
slA.reverse()
print(slA)
but i need to redefine the new tail object
I try to do it only with "swap" the inner link :
def reverse(self):
num=self.nbrElement()-1
pCourant = SimpleList()
tab = self
for i in range(0,num-1):
tabTmp = tab
tab = tab.cdr()
tabTmp.__cell = (tabTmp.car(),pCourant)
pCourant= tabTmp
self.__cell = neww = (tab.car(),pCourant)
There is a personn that can explain me this ???
Thanks for your help
Update :
def reverse(self):
num=self.nbrElement()-1
pCourant = SimpleList()
tab = self
for i in range(0,num):
tabTmp = tab
tab = tab.cdr()
tabTmp.__cell = (tabTmp.car(),pCourant)
pCourant= tabTmp
neww = SimpleList(tab.car(),pCourant)
print(neww)
print(neww)
self.__cell = neww.__cell
slA = SimpleList(10,SimpleList(9,SimpleList(8,SimpleList())))
slA.reverse()
print(slA.cdr().cdr().car())
print(slA)
Is notfor optimize my code ... But for understand, the "inner logic" of Python :
print(new) works well
a print(slA) do a "maximum recursion depth"
the penultimate display offer 8 but normally would display 10
Thanks for all
Since I'm still in the process of drinking my first cup of coffee, here's a simpler reimplementation.
(The __slots__ thing is a pre-optimization; you can elide it if you like.)
class ListCell:
__slots__ = ("value", "next")
def __init__(self, value, next=None):
self.value = value
self.next = next
def __repr__(self):
if not self.next:
return f"({self.value!r})"
else:
return f"({self.value!r},{self.next!r})"
def reverse(self):
prev = next = None
curr = self
while curr:
next = curr.next
curr.next = prev
prev = curr
curr = next
return prev # Return new head
#classmethod
def from_iterable(cls, items):
head = tail = None
for item in items:
if head is None:
head = tail = cls(item)
else:
tail.next = cls(item)
tail = tail.next
return head
lc = ListCell.from_iterable([1, 2, 4, 8])
print(lc)
lc = lc.reverse()
print(lc)
This prints out
(1,(2,(4,(8))))
(8,(4,(2,(1))))
I'm trying a leetcode min stack problem and my code is not working, tried finding a solution but can't see what's wrong. It seems to work for most inputs but fails "
["MinStack","push","push","push","top","pop","getMin","pop","getMin","pop","push","top","getMin","push","top","getMin","pop","getMin"]
[[],[2147483646],[2147483646],[2147483647],[],[],[],[],[],[],[2147483647],[],[],[-2147483648],[],[],[],[]]" .
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.stack = []
self.count = 0
self.minEle = -1
def push(self, x: int) -> None:
if self.count == 0:
self.minEle = x
self.stack.append(x)
elif x < self.minEle:
self.stack.append(2*x - self.minEle)
self.minEle = x
elif x >= self.minEle:
self.stack.append(x)
self.count += 1
def pop(self) -> None:
y = self.stack.pop()
if y < self.minEle:
self.minEle = 2*self.minEle - y
self.count -= 1
def top(self) -> int:
if self.count >=1:
return self.stack[(self.count - 1)]
else:
return 0
def getMin(self) -> int:
return self.minEle
Try:
class MinStack:
def __init__(self):
self.sc = []
self.sm = []
# #param x, an integer
# #return an integer
def push(self, x):
self.sc.append(x)
if x <= self.getMin():
self.sm.append(x)
return x
# #return nothing
def pop(self):
if self.sc.pop() == self.getMin():
self.sm.pop()
# #return an integer
def top(self):
return self.sc[-1]
# #return an integer
def getMin(self):
try:
return self.sm[-1]
except IndexError:
return self.top()
obj = MinStack()
obj.push(-2)
obj.push(0)
obj.push(-3)
print(obj.getMin())
obj.pop()
print(obj.top())
print(obj.getMin())
param_3 = obj.top()
param_4 = obj.getMin()
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.
I'm implementing a BST in Python but I have issues with but_insert(t, k).
Basically if I just add children to the root, like below, it works:
T = Node(7)
bst_insert(T, 9)
bst_insert(T, 5)
But if I insert another key, then an entire branch from the root seems to be dropped. For instance, if I execute:
T = Node(7)
bst_insert(T, 9)
bst_insert(T, 5)
bst_insert(T, 3)
Then when I print T in order I only get 7 9.
Here is the Node constructor and bst_insert (the print_in_order function works properly so I did not include it).
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def bst_insert(t, k):
if t is None:
t = Node(k)
elif k <= t.key:
if t.left is None:
t.left = Node(k)
else:
t.left = bst_insert(t.left, k)
else:
if t.right is None:
t.right = Node(k)
else:
t.right = bst_insert(t.right, k)
Thanks.
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def bst_insert(t, k):
if t is None:
t = Node(k)
elif k <= t.key:
if t.left is None:
t.left = Node(k)
else:
t.left = bst_insert(t.left, k) #1
else:
if t.right is None:
t.right = Node(k)
else:
t.right = bst_insert(t.right, k) #2
# return the node, #1 and #2 will always get None value
return t
from __future__ import annotations
class Node:
def __init__(self, value: int) -> None:
self.value = value
self.left = self.right = None
def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.value})"
class BST:
def __init__(self):
self.root = None
def add(self, root: Node, value: int) -> Node:
# if there is not root (empty node) -> then create new one
if root is None:
return Node(value)
if value <= root.value:
root.left = self.add(root.left, value)
else:
root.right = self.add(root.right, value)
return root
def print(self, root: Node) -> None:
"""Prints inorders BST values."""
if root is None:
return
self.print(root.left)
print(root.value, end=" ")
self.print(root.right)
if __name__ == "__main__":
values = [10, 6, 12, 3, 7, 4, 2]
bst = BST()
root = None
for value in values:
root = bst.add(root, value)
bst.print(root)
# output
# 2 3 4 6 7 10 12