python

时间:2017-12-03 15:53:50

标签: python binary-search-tree avl-tree

我正在做一个关于在python中实现AVL树的编码分配但是卡住了。赋值只要求我们执行元素插入和前驱查询。由于这是一项任务,老师要求我们从头开始构建代码。

我的代码逻辑很简单。我只定义了一个名为Node的类。每当元素插入树中时,我将根据需要执行旋转。但是,RLrotation()方法中出现错误,其中有一个语句B = c.rightchild。错误消息表示c是"无"所以它没有属性"右边的"。但是,在超过170,000次插入后出现错误,因此我不知道如何调试。

此外,我认为我的实施太复杂了。赋值允许最长运行时间为10秒,但我认为我的无法实现。我想知道是否有人可以建议我如何改进我的代码。

非常感谢您的帮助!

class Node:
  def __init__(self, key, parent):
    self.key = key
    self.parent = parent
    self.leftchild = None
    self.rightchild = None
    self.height = 1

  def insert(self, element):
    if element < self.key:
      self.insertleft(element)
    else:
      self.insertright(element)

  def insertleft(self, element):
    if self.leftchild != None:
      self.leftchild.insert(element)
    else:
      self.leftchild = Node(element, self)
      node = self
      self.height = 2
      while node.parent != None:
        node = node.parent
        if (node.rightchild != None) and (node.leftchild != None):
          if node.leftchild.height - node.rightchild.height > 1:
            node.leftrotate()
            return 0
          elif node.rightchild.height - node.leftchild.height > 1:
            node.rightrotate()
            return 0
          else:
            node.height = 1+max(node.leftchild.height, node.rightchild.height)
        elif node.leftchild == None:
          if node.rightchild.height == 2:
            node.rightrotate()
            return 0
          else:
            node.height = 2
        else:
          if node.leftchild.height == 2:
            node.leftrotate()
            return 0
          else:
            node.height = 2

  def insertright(self, element):
    if self.rightchild != None:
      self.rightchild.insert(element)
    else:
      self.rightchild = Node(element, self)
      node = self
      self.height = 2
      while node.parent != None:
        node = node.parent
        if (node.rightchild != None) and (node.leftchild != None):
          if node.leftchild.height - node.rightchild.height > 1:
            node.leftrotate()
            return 0
          elif node.rightchild.height - node.leftchild.height > 1:
            node.rightrotate()
            return 0
          else:
            node.height = 1+max(node.leftchild.height, node.rightchild.height)
        elif node.leftchild == None:
          if node.rightchild.height == 2:
            node.rightrotate()
            return 0
          else:
            node.height = 2
        else:
          if node.leftchild.height == 2:
            node.leftrotate()
            return 0
          else:
            node.height = 2

  def leftrotate(self):
    if self.leftchild.leftchild == None:
      self.LRrotation()
    elif self.leftchild.rightchild == None:
      self.LLrotation()
    elif self.leftchild.leftchild.height == self.height-1:
      self.LLrotation()
    else:
      self.LRrotation()

  def LLrotation(self):
    u = self.parent
    a = self
    b = self.leftchild
    B = b.rightchild
    C = a.rightchild
    a.parent = b
    a.leftchild = B
    if B != None:
      B.parent = a
    b.parent = u
    b.rightchild = a
    if u != None:
      if u.leftchild == a:
        u.leftchild = b
      else:
        u.rightchild = b
    if (B == None) or (C == None):
      a.height = 1
    else:
      a.height = 1+max(a.leftchild.height, a.rightchild.height)
    b.height = 1+max(b.leftchild.height,b.rightchild.height)

  def LRrotation(self):
    u = self.parent
    a = self
    b = self.leftchild
    c = b.rightchild
    B = c.leftchild
    C = c.rightchild
    a.parent = c
    a.leftchild = C
    b.parent = c
    b.rightchild = B
    c.parent = u
    c.leftchild = b
    c.rightchild = a
    if B != None:
      B.parent = b
    if C != None:
      C.parent = a
    if u != None:
      if u.leftchild == a:
        u.leftchild = c
      else:
        u.rightchild = c
    if b.height == 2:
      b.height = 1
    a.height -= 1
    c.height = a.height +1

  def rightrotate(self):
    if self.rightchild.rightchild == None:
      self.RLrotation()
    elif self.rightchild.leftchild == None:
      self.RRrotation()
    elif self.rightchild.rightchild.height == self.height-1:
      self.RRrotation()
    else:
      self.RLrotation()

  def RRrotation(self):
    u = self.parent
    a = self
    b = self.rightchild
    B = b.leftchild
    C = a.leftchild
    a.parent = b
    a.rightchild = B
    if B != None:
      B.parent = a
    b.parent = u
    b.leftchild = a
    if u != None:
      if u.rightchild == a:
        u.rightchild = b
      else:
        u.leftchild = b
    if (B == None) or (C == None):
      a.height = 1
    else:
      a.height = 1+max(a.leftchild.height, a.rightchild.height)
    b.height = 1+ max(b.leftchild.height,b.rightchild.height)

  def RLrotation(self):
    u = self.parent
    a = self
    b = self.rightchild
    c = b.leftchild
    B = c.rightchild
    C = c.leftchild
    a.parent = c
    a.rightchild = C
    b.parent = c
    b.leftchild = B
    c.parent = u
    c.rightchild = b
    c.leftchild = a
    if B != None:
      B.parent = b
    if C != None:
      C.parent = a
    if u != None:
      if u.rightchild == a:
        u.rightchild = c
      else:
        u.leftchild = c
    if b.height == 2:
      b.height = 1
    a.height -= 1
    c.height = a.height +1

  def query(self, value, result):
    if self.key == value:
      return value
    elif self.key > value:
      if self.leftchild != None:
        return self.leftchild.query(value, result)
      else:
        return result
    else:
      result = self.key
      if self.rightchild != None:
        return self.rightchild.query(value, result)
      else:
        return result

0 个答案:

没有答案