我实现了一个二进制搜索树,该树使用重复的值并将该值存储在一个节点中,并且该节点出现的次数为“ num”。我实现了一个添加节点的函数,如果有重复的节点,则该节点出现的次数将显示在输出中。
我正在尝试创建一个计数函数,该函数对元素在树中出现的次数进行计数。因此例如count(“ code”)应该返回2。
我也在尝试实现删除功能,以删除一个值,但是如果有重复项,则仅应删除该值之一。例如delete(“ code”)应该打印出(code,1),如果“ num”为0,则应删除整个节点。
这是我到目前为止所做的:
class Node:
def __init__(self,val,l,r):
self._data = val
self.num = 1
self._leftChild = l
self._rightChild = r
# prints the node and all its children in a string
def __str__(self):
st = "("+str(self._data)+", "+str(self.num)+") -> ["
if self._leftChild != None:
st += str(self._leftChild)
else: st += "None"
if self._rightChild != None:
st += ", "+str(self._rightChild)
else: st += ", None"
return st + "]"
def updateChild(self, oldChild, newChild):
if self._leftChild == oldChild:
self._leftChild = newChild
elif self._rightChild == oldChild:
self._rightChild = newChild
else: raise Exception("updateChild error")
class Tree:
def __init__(self):
self.root = None
self.size = 0
def __str__(self):
return str(self.root)
def isEmpty(self):
return self.root == None
def search(self, val, depth=1):
if not self.root:
return 0, 0
elif self.root._data == val:
return depth, self.root.num
elif val < self.root._data:
return search(self.root._leftChild, val, depth + 1)
else:
return search(self.root._rightChild, val, depth + 1
def add(self, val):
if self.root == None:
self.root = Node(val,None,None)
else:
pointer = self.root
while True:
if val < pointer._data:
if pointer._leftChild == None:
pointer._leftChild = Node(val,None,None)
break
pointer = pointer._leftChild
elif val == pointer._data:
pointer.num += 1
break
else:
if pointer._rightChild == None:
pointer._rightChild = Node(val,None,None)
break
pointer = pointer._rightChild
def count(self, val):
pointer = self.root
count = 0
while pointer != None:
pointer = self.search(pointer,val)
if pointer != None:
count += 1
count = pointer.num
pointer = pointer._rightChild
return count
def delete(self,val):
if self.root == None:
return
if self.root._data == val:
return self._removeRoot()
parentNode = None
currentNode = self.root
while currentNode != None and currentNode._data !=val:
if val < currentNode.data:
parentNode = currentNode
currentNode = currentNode._leftChild
else:
parentNode = currentNode
currentNode = currentNode._rightChild
if currentNode != None:
return self._removeNode(currentNode,parentNode)
# removes the node currentNode from the tree altogether
def _removeNode(self,currentNode,parentNode):
self.size -= 1
# 3 cases to consider:
# 1. the node to be removed is a leaf
if currentNode._leftChild == currentNode._rightChild == None:
parentNode.updateChild(currentNode,None)
# 2.node to be removed has exactly one child
elif currentNode._leftChild == None or currentNode._rightChild == None:
if currentNode._leftChild != None:
parentNode.updateChild(currentNode,currentNode._leftChild)
else:
parentNode.updateChild(currentNode,currentNode._rightChild)
# 3. node to be removed has both children
else:
parentMinNode = currentNode
minNode = currentNode._rightChild
while minNode._leftChild != None:
parentMinNode = minNode
minNode = minNode._leftChild
parentMinNode.updateChild(minNode,minNode._rightChild)
parentNode.updateChild(currentNode,minNode)
minNode._leftChild = currentNode._leftChild
minNode._rightChild = currentNode._rightChild
def _removeRoot(self):
parentNode = Node(None,self.root,None)
self._removeNode(self.root,parentNode)
self.root = parentNode._leftChild
这是使用上述类的示例:
t = Tree()
t.add("code"); t.add("pyt"); t.add("hello"); t.add("code")
t.add("java"); t.add("math"); t.add("Comp")
Output: (code, 2) -> [(Comp, 1) -> [None, None], (pyt, 1) -> [(hello, 1) -> [None, (java, 1) -> [None, (math, 1) -> [None, None]]], None]]
之后,当我这样做时:
print(t.count("code"),t.delete("code"),t.count("code"),t.size)
它应该打印:
2 None 1 6
结果应为:
(cat, 1) -> [(car, 1) -> [None, (cart, 1) -> [None, None]], (cav, 1) -> [None, (put, 1) ->
[(cs, 1) -> [None, None], None]]]