深度第一树搜索

时间:2014-06-23 19:03:23

标签: python python-2.7

我在python 2.7中tree structure上实现递归深度优先搜索时遇到问题,有人能指出我正确的方向吗?

代码

class node(object):
    def __init__(self, value,children=[]):
        self.value=value
        self.children=children
    def __repr__ (self,level=0):
        ret = "\t"*level+repr(self.value)+"\n"
        for child in self.children:
            ret +=child.__repr__(level+1)
        return ret  

    def search(self,st):
        if self.value==st:
            return True
        else:
            if not self.children:
                return False
            else:               
                for child in self.children:
                    self.search(st)

示例数据结构(用于简单粘贴):

tree = node("fashion",[
    node("garment",[
        node("t-shirt"),
        node("shorts")]),
    node("designer",[
        node("Ralf"),
        node("tommy"),
        node("joe")])
    ])

编辑:问题是我在搜索时以无限循环结束,例如:

tree.search("garment")

编辑2:更新以修复递归而不推进(感谢Ben!),但没有得到tree.search(“joe”)的错误答案

    def search(self,st):
    if self.value==st:
        return True
    else:
        if self.children:
            for child in self.children:
                return child.search(st)             
        else:               
            return False

编辑3:Sharth的敏锐观察导致我

def search(self,st):
    if self.value==st:
        return True
    for child in self.children:
        if child.search(st):
            return True         
    return False

哪个效果很好,但搜索

>>>tree.search("p")

产生

  

Traceback(最近一次调用最后一次):文件“”,第1行,in          tree.search(“p”)文件“”,第15行,在搜索中       if child.search(st):AttributeError:'list'对象没有属性'search'

为什么会这样?

EDIT4:在使用上述数据结构时有效,但在第三级数据时失败,即

tree = node("fashion",[
    node("garment",[
        node("t-shirt"),
        node("shorts")]),
    node("designer",[
        node("Ralf"),
        node("tommy"),
        node("joe"),[
        node("fresh")]
    ])
    ])

编辑5:在编辑四中搞砸了大括号。多么虚伪。感谢所有人的帮助!!

3 个答案:

答案 0 :(得分:1)

在以下代码中,修复了3个问题:

  1. Mutable default arguments
  2. 循环播放时,我们需要拨打child.search(st),而不是self.search(st)
  3. 我们不想只看第一个孩子(正如你的第二个编辑所做的那样),我们希望在第一个孩子身上恢复成功。如果第一个是假的,我们想尝试下一个..
  4. 所以,代码:

    class node(object):
        def __init__(self, value, children=None):
            self.value = value
            self.children = children or []
    
        def search(self, st):
            if self.value == st:
                return True
            for child in self.children:
                 if child.search(st):
                     return True
            return False
    

答案 1 :(得分:1)

看起来您的搜索功能实际上并没有搜索孩子。试试这个:

def search(self,st):
    if self.value==st:
        return True
    else:
        if not self.children:
            return False
        else:               
            return any(child.search(st) for child in self.children)

请注意,最后一行已被修改为将generator expression与内置函数any结合使用,以便按顺序搜索每个子节点,并在其中一个子节点中立即停止结果为True

这里的主要区别是我们拨打child.search(st)而不是self.search(st)

另请注意,当children为空时,您确实不需要单独的案例,因此您可以这样做:

def search(self,st):
    if self.value==st:
        return True
    else:
        return any(child.search(st) for child in self.children)

这可以进一步简化:

def search(self,st):
    return self.value==st or any(child.search(st) for child in self.children)

当你返回一个布尔文字时,这是一个好兆头,你可以通过使用and / or来简化。

答案 2 :(得分:0)

请将孩子设置为无,而不是列表。将可变参数作为默认参数非常危险。请参阅Hidden features of Python以供参考。儿童的价值可能不是一个空的清单,即使其意图是。