首先看BST是否为空,如果一个节点都没有,那么key成为根节点root,否则,就调用一个递归函数_put(key, val, root)来放置key
如果key比currentNode小,那么_put到左子树
但如果没有左子树,那么key就成为左子节点如果key比currentNode大,那么_put到右子树
但如果没有右子树,那么key就成为右子节点 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)可以myZipTree[‘PKU’] = 100871
def __setitem__(self, k, v): self.put(k, v)实现val= myZipTree[‘PKU’]
实现’PKU’ in myZipTree的归属判断运算符in
def __getitem__(self, key): return self.get(key) def __contains__(self, key): if self._get(key, self.root): return True else: return FalseADT Map也应该实现这样的迭代器功能
BST类中的__iter__方法直接调用了TreeNode中的同名方法
迭代器函数中用了for迭代,实际上是递归函数,yield是对每次迭代的返回值中序遍历的迭代
def __iter__(self): if self: if self.hasLeftChild(): for elem in self.leftChild: yield elem yield self.key if self.hasRightChild(): for elem in self.rightChild: yield elem用_get找到要删除的节点,然后调用remove来删除,找不到则提示错误
def delete(self, key): if self.size > 1: nodeToRemove = self._get(key, self.root) if nodeToRemove: self.remove(nodeToRemove) self.size = self-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')实现del myZipTree[‘PKU’]这样的语句操作
def __delitem__(self, key): self.delete(key)这个节点没有子节点 这个节点有1个子节点 这个节点有2个子节点
解决:将这个唯一的子节点上移,替换掉被删节点的位置
被删节点的子节点是左?还是右子节点? 被删节点本身是其父节点的左?还是右子节点? 被删节点本身就是根节点?
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)这时无法简单地将某个子节点上移替换被删节点,但可以找到另一个合适的节点来替换被删节点,这个合适节点就是被删节点的下一个key值节点,即被删节点右子树中最小的那个,称为“后继”
按照从小到大顺序插入的话,如下图这时候put方法的性能为O(n),其它方法也是类似情况