2013-03-05 2 views
9

Я новичок в программировании и пытаюсь вычислить глубину дерева python. Я считаю, что моя ошибка заключается в том, что глубина - это метод класса Node, а не регулярная функция. Я пытаюсь изучить oop и надеялся использовать метод. Это может быть новая ошибка пчелиный ... Вот мой код:глубина дерева python

class Node: 

    def __init__(self, item, left=None, right=None): 
     """(Node, object, Node, Node) -> NoneType 
     Initialize this node to store item and have children left and right. 
     """ 
     self.item = item 
     self.left = left 
     self.right = right 

    def depth(self): 
     if self.left == None and self.right == None: 
      return 1 

     return max(depth(self.left), depth(self.right)) + 1 

i receive this error: 

>>>b = Node(100) 

>>>b.depth() 

1 

>>>a = Node(1, Node(2), Node(3)) 

>>>a.depth() 

Traceback (most recent call last): 
    File "C:\Program Files\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 1, in <module> 
    # Used internally for debug sandbox under external interpreter 
    File "C:\Program Files\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 15, in depth 
builtins.NameError: global name 'depth' is not defined 
+0

+1 для правильной интуиции вашей проблемы. –

+1

В будущем, я считаю, что 'новая пчела' написана' newbie', если я не ошибаюсь. –

+0

Интуиция частично корректна (вызов 'depth()' как метод решает проблему), но несколько неполный. Основная причина, объясняющая, почему вы не можете получить доступ к методу изнутри, но вы можете с помощью регулярной функции, - это несколько подробная информация о том, как сфера и определение класса работают в Python. Когда вы вызываете регулярную функцию уровня модуля, это «глобальная» область видимости будет определяемым модулем, который содержит эту функцию. Однако область определения методов может считаться отброшенной после создания объекта типа. – millimoose

ответ

7
def depth(self): 
    if self.left == None and self.right == None: 
     return 1 

    return max(depth(self.left), depth(self.right)) + 1 

должен быть

def depth(self): 
    return max(self.left.depth() if self.left else 0, self.right.depth() if self.right else 0) + 1 

Более читаемый версия:

def depth(self): 
    left_depth = self.left.depth() if self.left else 0 
    right_depth = self.right.depth() if self.right else 0 
    return max(left_depth, right_depth) + 1 

Этот вопрос что нет функции depth. Это метод объекта Node, поэтому вам нужно будет вызвать его из самого объекта (слева и справа). Я укоротил код до self.left.depth() if self.left else 0 и self.right.depth() if self.right else 0, чтобы удалить ранее сделанные вами проверки (они теперь неявны), поскольку я считаю, что вполне возможно, что слева находится None, а справа - Node или наоборот, что приведет к исходный код для броска AttributeError, так как None не имеет способа depth.

Редактировать

В ответ на вопрос о <something> if <some condition> else <otherwise> блока:

линия дает <something> если <some condition> истинно-у (трактуется как верно), и <otherwise> если <some condition> ложно-у (обработано как ложное)

+0

Я считаю, что вы хотите называть 'depth', так как это функция :) – Wolph

+1

Мембрание его в одну строку немного нечитаемо, но это правильный ответ. – Hamish

+0

Не будет 'Node' нужен' '__bool__' или' __nonzero__' метод для 'if self.left' тестов на самом деле работать? – Marius

2

Для ясности я бы предложил написать ваш метод depth следующим образом:

def depth(self): 
    current_depth = 0 

    if self.left: 
     current_depth = max(current_depth, self.left.depth()) 

    if self.right: 
     current_depth = max(current_depth, self.right.depth()) 

    return current_depth + 1 
+3

Для ясности я бы предложил не использовать одно и то же имя для метода и локальную переменную в нем. – millimoose

+0

Итак, все узлы имеют одинаковую глубину 1? Почему это? – Hyperboreus

+0

@Hyperboreus: это по существу то, что делал его код, я не проверял правильность. Просто дал более читаемый рисунок :) – Wolph

1

ошибка исходит от этой линии:

return max(depth(self.left), depth(self.right)) + 1 

Вы используете глубину как функцию и пытаетесь применить его к левым и правым узлам. Поскольку левый и правый узлы также являются узлами, они имеют метод глубины.

Вы должны вызвать метод глубины, как это:

return max(self.left.depth(), self.right.depth()) + 1 

Параметр самости неявно передаются методе глубины, но при использовании его с помощью оператора точки говорит Python, что этот метод принадлежит к экземпляру Node, и это не какая-то другая функция, не связанная с объектом.

0

У вас есть четыре случая, чтобы рассмотреть:

  1. Оба поддеревья пусты.
  2. Левое поддеревье пусто.
  3. Право только поддерева пусто.
  4. Ни поддерева пуста.

Вы рассмотрели случаи 1 и 4, но пропустили 2 и 3. Исправление:

# Return height of tree rooted at this node. 
def depth(self): 
    if self.left == None and self.right == None: 
     return 1 
    elif self.left == None: 
     return self.right.depth() + 1 
    elif self.right == None: 
     return self.left.depth() + 1 
    else: 
     return max(self.left.depth(), self.right.depth()) + 1 
Смежные вопросы