Rema Thomas Ответов: 1

Исправьте функцию inorder моей программы Python


У меня есть эта программа, которая должна распечатать красно-черное дерево в python, но когда я иду, чтобы запустить эту программу, все, что я получаю, - это 65 черных. Есть и другие числа, которые должны быть в выходном операторе, но все, что я получаю, - это сообщение об ошибке "RecursionError: максимальная глубина рекурсии превышена при вызове объекта Python." Я не уверен, что Хоу это исправит. Пожалуйста, помогите! Спасибо!

Что я уже пробовал:

class TreeNode:
   def __init__(self,val,left = None,right = None, parent = None,color = None):
      self.val = val
      self.leftChild = left
      self.rightChild = right
      self.parent = parent
      self.color = color
   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))
   
   
class BST(TreeNode):
   def __init__(self):
      self.root = None
      self.size = 0
      self.nil = TreeNode(None)
      self.nil.color = "black"
   def addNode(self,val):
      self.size += 1
      y = self.nil
      x = self.root
      if self.root == None:
         self.root = TreeNode(val,self.nil,self.nil,self.nil,"black")
      else:
         z = TreeNode(val,self.nil,self.nil, None, "red")
         while x!= self.nil:
            y = x
            if z.val < x.val:
               x = x.hasLeftChild()
            else:
               x = x.hasRightChild()
         z.parent = y 
         if y == self.nil:
            self.root = z
         elif z.val < y.val:
            y.leftChild = z
         else:
            y.rightChild = z
         self.treeInsFixer(z)
   def treeInsFixer(self,z):
      while z.parent.color == "red":
         if z.parent == z.parent.parent.leftChild:
            y = z.parent.parent.rightChild
            if y.color == "red":
               z.parent.color = "black"
               y.color = "black"
               z.parent.parent.color = "red"
               z = z.parent.parent
            else:
               if z == z.parent.rightChild:
                  z = z.parent
                  self.leftRotate(z)
               z.parent.color = "black"
               z.parent.parent.color = "red"
               self.rightRotate(z.parent.parent)
         elif z.parent == z.parent.parent.rightChild:
            y = z.parent.parent.leftChild
            if y.color == "red":
               z.parent.color = "black"
               y.color = "black"
               z.parent.parent.color = "red"
               z = z.parent.parent
            else:
               if z == z.parent.leftChild:
                  z = z.parent
                  self.rightRotate(z)
               z.parent.color = "black"
               z.parent.parent.color = "red"
               self.leftRotate(z.parent.parent)
      self.root.color = "black"               
   def leftRotate(self,x):
      y = x.rightChild
      x.rightChild = y.leftChild
      if y.leftChild != self.nil:
         y.leftChild.parent = x
      y.parent = x.parent
      if x.parent == self.nil:
         self.root = y
      elif x == x.isLeftChild():
         x.parent.leftChild = y
      else:
         x.parent.rightChild = y
      y.leftChild = x
      x.parent = y
   def rightRotate(self,x): 
      y = x.leftChild
      x.leftChild = y.rightChild
      if y.rightChild != self.nil:
         y.rightChild.parent = x
      y.parent = x.parent
      if x.parent == self.nil:
         self.root = y 
      elif x == x.isRightChild():
         x.parent.rightChild = y
      else:
         x.parent.leftChild = y
      y.rightChild = x 
      x.parent = y
#This is where the error keeps occuring
   def  inOrder(self,x):
      if x != self.nil:
         self.inOrder(x.leftChild)
         print(x.val, x.color)
         self.inOrder(x.rightChild)

a = BST()
a.addNode(80)
a.addNode(1)
a.addNode(50)
a.addNode(65)
a.addNode(90)
a.inOrder(a.root)

Afzaal Ahmad Zeeshan

В чем же ошибка?

phil.o

RecursionError: максимальная глубина рекурсии превышена при вызове объекта Python.

Afzaal Ahmad Zeeshan

Я думаю, что это очень плохо, если Python не может обрабатывать даже небольшой объем данных, не так ли?

OP должен был бы использовать итеративное решение для этого. :facepalm:

phil.o

Действительно, было бы плохо не справиться с небольшим количеством рекурсии.
Теперь остается необходимость убедиться, что это вина питона :) Не могу сказать, что я действительно не занимаюсь питоном. И я стараюсь избегать рекурсии, насколько это возможно, поскольку итеративный способ никогда не вызовет переполнения стека.

1 Ответов

Рейтинг:
0

OriginalGriff

Это будет зависеть от размера ваших данных: Python имеет ограничение рекурсии по умолчанию в 999 вызовов (хотя это можно изменить с помощью Метод Python | sys.setrecursionlimit () - GeeksforGeeks[^]) если только ваш тестовый dtaa не содержит 1000 элементов или более - а я сомневаюсь, что для такого раннего кода - увеличение лимита только заставит вас немного дольше ждать появления ошибки.

Рекурсия (как я уверен, вы знаете) - это когда функция вызывает саму себя, либо напрямую, используя имя функции внутри функции, либо косвенно, вызывая функцию, которая вызывает первую функцию. Иногда это то, что вы хотите, и классический пример-Факториал:

Factorial(n) == n * Factorial(n - 1)
При условии, что Факториальная функция включает проверку на "один или ниже" для завершения рекурсии, она работает хорошо. (Итеративное решение более эффективно, но Факториал часто используется для демонстрации концепции).
Однако если вы опустите проверку завершения, Факториальная функция просто продолжит вызывать себя до тех пор, пока у машины, выполняющей ее, не закончится память для хранения там, куда она должна вернуться, и приложение не выйдет из строя.
Python ограничивает это, имея очень небольшое ограничение на то, как "глубокая" рекурсия может идти - 999 вызовов по умолчанию.

Ваше приложение превышает это значение по умолчанию, и если у вас нет более 999 элементов в одной ветви дерева, это означает, что в вашем коде отсутствует проверка завершения или в вашем дереве действительно есть цикл.

Я бы посоветовал вам воспользоваться отладчик[^] чтобы точно следить за тем, что происходит, и выяснить, является ли это проблемой кода или данных.

Извините, но мы не можем сделать это для вас!