2016-09-16 93 views
1

我在python中尝试了一点OOP,同时在数据结构上做功课,并且在理解如何纠正继承某些方法和纠正方面遇到了一些麻烦。正确的方式继承方法1更正

所以,我有:

class BinarySearchTree(object): 
    # snipped 
    def _insert(self, key, val): 
     prevNode = None 
     currentNode = self.root 
     while currentNode: 
      prevNode = currentNode 
      if key < currentNode.key: 
       currentNode = currentNode.leftChild 
      else: 
       currentNode = currentNode.rightChild 

     if key < prevNode.key:      
      prevNode.leftChild = self.Node(key, val, parent=prevNode) 
      self.updateNodeProperties(prevNode.leftChild)    
     else:          
      prevNode.rightChild = self.Node(key, val, parent=prevNode) 
      self.updateNodeProperties(prevNode.rightChild) 
    # snipped     

和:

class RBTree(BinarySearchTree): 
    # snipped 
    def _insert(self, key, val): 
     prevNode = None 
     currentNode = self.root 
     while currentNode: 
      prevNode = currentNode 
      prevNode.size += 1 # The only difference is in this line 
      if key < currentNode.key: 
       currentNode = currentNode.leftChild 
      else: 
       currentNode = currentNode.rightChild 

     if key < prevNode.key:      
      prevNode.leftChild = self.Node(key, val, parent=prevNode) 
      self.updateNodeProperties(prevNode.leftChild)    
     else:          
      prevNode.rightChild = self.Node(key, val, parent=prevNode) 
      self.updateNodeProperties(prevNode.rightChild) 
    # snipped 

而且有我的问题:有没有继承这个方法,而不复制整个意识到这1个差异(prevNode.size += 1)聪明的办法继承的功能代码?

小姐:抱歉我的英语不好。

UPD:现在我不能斯科特和CAB的解决方案之间进行选择...

+1

否这是您将如何使用去做吧。如果你只修改一次节点,那将是一回事,但是因为它是循环的,所以你必须重新实现这个方法。 –

+0

你可以拥有'prevNode.size + = self.something'并且适当的设置(默认为'0')。 – jonrsharpe

+1

对于[关注点分离](https://en.wikipedia.org/wiki/Separation_of_concerns),您的树类中的代码应该管理树,而不是在节点本身中摆弄。访问者设计模式是一个很好的方法。 – CAB

回答

1

假设prevNode也是BTreeRBTree,您可以添加另一种方法,说“updateSize`,并包括行

prevNode.updateSize() 

BTree,这将无能为力。但是,如果将RBTree设置为BTRee的子类,则可以覆盖此方法以将1添加到节点的大小。

1

下面是使用Visitor设计模式的建议。

在这种模式中,你正在编写一个访问者方法,而不是知道每个访问的节点需要做什么。

我们将更改基类以添加访问者能力;

class BinarySearchTree(object): 
# snipped 
def _insert(self, key, val, visitor=None): # Change here 
    prevNode = None 
    currentNode = self.root 
    while currentNode: 
     prevNode = currentNode 
     if visitor: visitor(prevNode)  # Change here 
     if key < currentNode.key: 
      currentNode = currentNode.leftChild 
     else: 
      currentNode = currentNode.rightChild 

    if key < prevNode.key:      
     prevNode.leftChild = self.Node(key, val, parent=prevNode) 
     self.updateNodeProperties(prevNode.leftChild)    
    else:          
     prevNode.rightChild = self.Node(key, val, parent=prevNode) 
     self.updateNodeProperties(prevNode.rightChild) 
# snipped 

现在你的第二课;

class RBTree(BinarySearchTree): 
# snipped 
def _insert(self, key, val): 
    visitor = lambda node: node.size += 1 
    super(RBTree, self)._insert(self, key, val, visitor) 
# snipped 
+0

Big thx,但是当你写答案时,我做了同样的事情,因为你对原帖的评论:) – KgOfHedgehogs

2

这不完全优雅,但你可以做这样的事情:

class BinarySearchTree(object): 
    def _insert(self, key, val, update=False): 
     prevNode = None 
     currentNode = self.root 
     while currentNode: 
      prevNode = currentNode 
      if update: 
       prevNode.size += 1 
      if key < currentNode.key: 
       currentNode = currentNode.leftChild 
      else: 
       currentNode = currentNode.rightChild 

     if key < prevNode.key:      
      prevNode.leftChild = self.Node(key, val, parent=prevNode) 
      self.updateNodeProperties(prevNode.leftChild)    
     else:          
      prevNode.rightChild = self.Node(key, val, parent=prevNode) 
      self.updateNodeProperties(prevNode.rightChild) 
    # snipped 

class RBTree(BinarySearchTree): 
    # snipped 

    def _insert(self, key, val): 
     super(RBTree, self)._insert(self, key, val, update=True) 

我真的不喜欢,因为它在你的BinarySearchTree类更新没有按一个实例变量的代码除了派生的RBTree类中不存在,但由于该部分代码不应该为BinarySearchTree实例执行,所以您不应该遇到NameError ...