Python 使用AVL树实现字典,我不';我不知道我在哪里;我错了
但我不知道我错在哪里我担心,由于信息太少,代码太多,你不会得到有用的答案。Python 使用AVL树实现字典,我不';我不知道我在哪里;我错了,python,dictionary,avl-tree,Python,Dictionary,Avl Tree,但我不知道我错在哪里我担心,由于信息太少,代码太多,你不会得到有用的答案。 class TreeNode: def __init__(self, key, val, left=None, right=None, parent=None): self.key = hash(key) self.originalkey = key self.payload = val self.leftChild = left
class TreeNode:
def __init__(self, key, val, left=None, right=None, parent=None):
self.key = hash(key)
self.originalkey = key
self.payload = val
self.leftChild = left
self.rightChild = right
self.parent = parent
self.balanceFactor = 0
def getLeft(self):
return self.leftChild
def getRight(self):
return self.rightChild
hasLeftChild = getLeft
hasRightChild = getRight
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.leftChild or self.rightChild)
def hasAnyChildren(self):
return self.leftChild or self.rightChild
def hasBothChildren(self):
return self.leftChild and self.rightChild()
def replacNodeData(self, key, val, leftChild, rightChild):
self.key = hash(key)
self.originalkey = key
self.payload = val
self.leftChild = leftChild
self.rightChild = rightChild
if self.hasLeftChild():
self.leftChild.parent = self
if self.hasRightChild():
self.rightChild.parent = self
def replaceNodeValue(self,key,val):
self.key = hash(key)
self.originalkey = key
self.payload = val
def __str__(self):
leftChildstr = f"[{str(self.leftChild)}]" if self.leftChild else '[]'
rightChildstr = f"[{str(self.rightChild)}]" if self.rightChild else "[]"
return f"[{repr(self.originalkey)}/{self.balanceFactor},{leftChildstr},{rightChildstr}]"
__repr__ = __str__
def __iter__(self):
if self.hasLeftChild():
for originalkey in self.leftChild:
yield originalkey
yield self.originalkey
if self.hasRightChild():
for originalkey in self.rightChild:
yield originalkey
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 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
class AVLTree:
def __init__(self):
self.root = None
self.size = 0
def __len__(self):
return self.size
def __iter__(self):
if self.root:
return iter(self.root)
return iter([])
def __str__(self):
allstr = ', '.join([f"{repr(key)}:{repr(self[key])}" for key in self])
return f"{{{allstr}}}"
def put(self,key,val):
if self.root:
self._put(key,val,self.root)
else:
self.root = TreeNode(key,val)
self.size = 1
def _put(self,key,val,currentNode):
originalkey = key
key = hash(originalkey)
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(originalkey, val, currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(originalkey, val, parent=currentNode)
self.size += 1
self.updateBalance(currentNode.leftChild)
elif key > currentNode.key:
if currentNode.hasRightChild():
self._put(originalkey, val, currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(originalkey, val, parent=currentNode)
self.size += 1
self.updateBalance(currentNode.rightChild)
else:
currentNode.replaceNodeValue(originalkey, val)
def updateBalance(self,node):
if node.balanceFactor > 1 or node.balanceFactor < -1:
self.rebalance(node)
return
if node.parent:
if node.isLeftChild():
node.parent.balanceFactor += 1
elif node.isRightchild():
node.parent.balanceFactor -= 1
if node.parent.balanceFactor != 0:
self.updateBalance(node.parent)
def rebalance(self, node):
if node.balanceFactor < 0:
if node.rightChild.balanceFactor > 0:
self.rotateRight(node.rightChild)
self.rotateLeft(node)
else:
self.rotateLeft(node)
elif node.balanceFactor > 0:
if node.leftChild.balanceFactor < 0:
self.rotateLeft(node.leftChild)
self.rotateRight(node)
else:
self.rotateRight(node)
def rotateLeft(self, rotRoot):
newRoot = rotRoot.rightChild
rotRoot.rightChild = newRoot.leftChild
if newRoot.hasLeftChild():
newRoot.leftChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isLeftChild():
rotRoot.parent.leftChild = newRoot
else:
rotRoot.parent.rightChild = newRoot
newRoot.leftChild = rotRoot
rotRoot.parent = newRoot
rotRoot.balanceFactor = rotRoot.balanceFactor + 1 - min(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor + 1 + max(rotRoot.balanceFactor, 0)
def rotateRight(self, rotRoot):
newRoot = rotRoot.leftChild
rotRoot.leftChild = newRoot.leftChild
if newRoot.hasRightChild():
newRoot.rightChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isLeftChild():
rotRoot.parent.leftChild = newRoot
else:
rotRoot.parent.rightChild = newRoot
newRoot.rightChild = rotRoot
rotRoot.parent = newRoot
rotRoot.balanceFactor = rotRoot.balanceFactor - 1 - max(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor - 1 + min(rotRoot.balanceFactor, 0)
def get(self, key):
return self._get(key, self.root).payload
__getitem__ = get
def _get(self,key,currentNode):
originalkey = key
key = hash(originalkey)
if not currentNode:
raise KeyError(originalkey)
elif key == currentNode.key:
return currentNode
elif key < currentNode.key:
return self._get(originalkey, currentNode.leftChild)
else:
return self._get(originalkey, currentNode.rightChild)
def __contains__(self,key):
try:
v = self[key]
except KeyError:
return False
return True
def delete(self,key):
originalkey = key
key = hash(originalkey)
if self.size > 1:
nodeToRemove = self._get(originalkey, self.root)
if nodeToRemove:
self.remove(nodeToRemove)
self.size -= 1
else:
raise KeyError(originalkey)
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = 0
else:
raise KeyError(originalkey)
__delitem__ = delete
def remove(self, currentNode):
if currentNode.isLeaf():
if currentNode.isLeftChild():
currentNode.parent.leftChild = None
currentNode.parent.balanceFactor -= 1
else:
currentNode.parent.rightChild = None
currentNode.parent.balanceFactor += 1
self.updateBalanceRemove(currentNode.parent)
elif currentNode.hasBothChildren():
succ = currentNode.findSuccessor()
if succ.isLeftChild():
succ.parent.balanceFactor -= 1
else:
succ.parent.balanceFactor += 1
succ.spliceOut()
currentNode.replaceNodeValue(succ.originalkey, succ.payload)
self.updateBalanceRemove(succ.parent)
else:
if currentNode.hasLeftChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
currentNode.parent.balanceFactor -= 1
elif currentNode.isRightchild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
currentNode.parent.balanceFactor += 1
else:
currentNod.leftChild.parent = None
self.root = currentNode.leftChild
else:
if currentNode.isLeftChild():
currentNode.rightChild.parent = currentNode.parent()
currentNode.parent.leftChild = currentNode.rightChild
currentNode.parent.balanceFactor -= 1
elif currentNode.isRightchild():
currentNode.rightChild.parent = currentNode.parent()
currentNode.parent.rightChild = currentNode.rightChild
currentNode.parent.balanceFactor += 1
else:
currentNode.rightChild.parent = None
self.root = currentNode.rightChild
if currentNode.parent:
self.updateBalanceRemove(currentNode.parent)
def updateBalanceRemove(self,node):
if node.balanceFactor > 1 or node.balanceFactor < -1:
self.rebalance(node)
node = node.parent
if node.balanceFactor == 0 and node.parent:
if node.isLeftChild():
node.parent.balanceFactor -= 1
elif node.isRightChild():
node.parent.balanceFactor += 1
self.updateBalanceRemove(node.parent)
class mydict:
def getRoot(self):
return self.avlTree.root
def __init__(self):
self.avlTree = AVLTree()
def __setitem__(self, key, value):
# md[key]=value
self.avlTree[key] = value
def __getitem__(self, key):
# v = md[key]
return self.avlTree[key]
def __delitem__(self, key):
# del md[key]
del self.avlTree[key]
def __len__(self):
# l = len(md)
return len(self.avlTree)
def __contains__(self, key):
# k in md
return key in self.avlTree
def clear(self):
sefl.avlTree = AVLTree()
def __str__(self):
#{'name': 'sessdsa', 'hello': 'world'}
return str(self.avlTree)
__repr__ = __str__
def keys(self):
keylist = []
for k in self.avlTree:
keylist.append(k)
return keylist
def values(self):
valuelist = []
for k in self.avlTree:
valuelist.append(self.avlTree[k])
return valuelist
#mydict=dict
print("========= AVLTree dictionary =========")
md = mydict()
md['hello'] = 'world'
md['name'] = 'sessdsa'
print(md) # {'name': 'sessdsa', 'hello': 'world'}
for f in range(1000):
md[f**0.5] = f
for i in range(1000, 2000):
md[i] = i**2
print(len(md)) # 2002
print(md[2.0]) # 4
print(md[1000]) # 1000000
print(md['hello']) # world
print(20.0 in md) # True
print(99 in md) # False
del md['hello']
print('hello' in md) # False
for i in range(1000, 2000):
del md[i]
print(len(md)) # 1001
for f in range(1000):
del md[f**0.5]
print(len(md)) # 1
print(md.keys()) # ['name']
print(md.values()) # ['sessdsa']
for a in md.keys():
print(md[a]) # sessdsa
md.clear()
print(md) # {}
AttributeError: __setitem__