代码不工作树BFS搜索

时间:2018-05-31 06:35:07

标签: python tree breadth-first-search

我编写了一个树级别的顺序遍历,虽然我的代码输出正确,但它会抛出一个

  

第21行:AttributeError:'NoneType'对象没有属性'val'

我知道其中一个值正在返回Null而我找不到。

# Definition for a binary tree node. 
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

import queue
class Solution(object):
    def levelOrder(self, root):
        L = queue.Queue()
        local = []
        result = []
        L.put(root)
        counter = 0
        while not L.empty():
            counter = L.qsize()
            local = []
            while counter >0:
                node = L.get()
                local.append(node.val)
                if(node.left):
                    L.put(node.left)
                if(node.right):
                    L.put(node.right)
                counter -=1
            result.append(local)   
        return result

1 个答案:

答案 0 :(得分:0)

如果您尝试实施真正的广度优先搜索,则可以使用getattr简化解决方案,以处理存储{{1}的树叶(leftright属性}})和None,用于从两端进行更简单的元素访问。请注意,collections.deque包含collections.deque方法,因此,您不需要在__bool__循环中进行显式大小比较。出于演示目的,下面的代码使用while方法创建完整的二叉树以进行答案验证,然后提供解决方案类。另外,要查找树级别顺序,如this类似问题中所述,您可以使用递归来获得更简单的结果:

二叉树实现:

__repr__

解决方案:

import collections, random
class Tree:
  full_nodes = []
  def __init__(self, **kwargs):
     self.__dict__ = {i:kwargs.get(i) for i in ['left', 'right', 'value']}
     Tree.full_nodes.append(kwargs.get('value'))
  def __bool__(self):
     return bool(getattr(self, 'value'))
  def __lt__(self, _node):
    return self.value < getattr(_node, 'value', _node)
  def insert_val(self, val):
    if self.value is None:
       self.value = val
    else:
       if val < self.value:
         if self.left is None:
           self.left = Tree(value = val)
         else:
           self.left.insert_val(val)
       else:
         if self.right is None:
           self.right = Tree(value = val)
         else: 
           self.right.insert_val(val)
  def __repr__(self):
    return f'<tree storing nodes {list(filter(None, Tree.full_nodes))}>'
  @classmethod
  def load_tree(cls, num=10, bounds = [1, 100]):
     _t = cls()
     for i in range(num):
        _t.insert_val(random.choice(range(*bounds)))
     return _t

运行解决方案:

class Solution:
  @staticmethod
  def bfs(tree, _to_find):
    queue = collections.deque([tree])
    seen = []
    while queue:
      _current = queue.popleft()
      if getattr(_current, 'value', None) == _to_find:
         return True
      l = list(filter(None, [getattr(_current, i, None) for i in ['left', 'right'] if getattr(_current, i, None) not in seen]))
      queue.extend(l)
      seen.extend(l)
    return False
  @staticmethod
  def level_nodes(tree):
    return [list(filter(None, [*(Solution.level_nodes(tree.left) if isinstance(tree.left, Tree) else [tree.left]), tree.value, *(Solution.level_nodes(tree.right) if isinstance(tree.right, Tree) else [tree.right])]))]
  @classmethod
  def pretty_nested(cls, t):
     if t:
       yield [t.value]
       yield [*(list(cls.pretty_nested(getattr(t, 'left', None))) if hasattr(t, 'left') else [None]), *(list(cls.pretty_nested(getattr(t, 'right', None))) if hasattr(t, 'right') else [None])]