实现二进制搜索树以处理Python中的重复键

时间:2014-12-06 18:58:47

标签: python binary-search-tree

下面是网站上给出的示例中的代码,我发现它可以帮助我更好地学习python:Interactive Python

作者解释说:

  

我们实现insert的一个重要问题是重复键未正确处理。当我们的树被实现时,重复的密钥将在具有原始密钥的节点的右子树中创建具有相同密钥值的新节点。结果是在搜索期间永远不会找到具有新密钥的节点。处理重复键的插入的更好方法是使用与新键关联的值来替换旧值。 我们将此错误修复为您的练习。"

我的问题是,如何解决此问题以正确处理重复密钥?如果树中已存在密钥,则新的有效负载应替换旧值。目标是不添加具有相同密钥的另一个节点,但我不知道在哪里开始这样做。我不确定为什么会这么混乱。

class BinarySearchTree:

    def __init__(self):
        self.root = None
        self.size = 0

    def length(self):
        return self.size

    def __len__(self):
        return self.size

    def __iter__(self):
        return self.root.__iter__()

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

    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)

1 个答案:

答案 0 :(得分:3)

_put()方法执行测试和插入,从不测试相等性。它仅测试插入的key是否较小(将键插入左子),否则它将插入到右子中。

只需测试相等性并替换:

def _put(self,key,val,currentNode):
    if key == currentNode.key:
        currentNode.value = val

    elif 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)