树遍历中的高阶函数

时间:2014-10-19 02:25:51

标签: python recursion functional-programming higher-order-functions tree-traversal

如何在传递函数以减少冗余的同时创建常见的树操作(如插入和搜索)。例如,当传入的值大于当前节点时,递归函数会在左分支上调用自身。如果我能够传递插入和搜索等功能,我就能够分解出很多遍历。我看到的主要问题是两个函数都有不同的基本情况。 python中的示例解决方案将不胜感激。

def insert(n, node = root):
    if node == None:
        node.data = n
        node.left, node.right, node.middle = None
    elif node.data == n:
        insert(node.middle)
    elif node.data < n:
        insert(right)
    else:
        insert(left)


def search(n, node = root):
    if node == None:
        return false
    elif node.data == n:
        return true
    elif node.data < n:
        search(right)
    else:
        search(left)

2 个答案:

答案 0 :(得分:0)

您插入的逻辑不正确。您正尝试在None上设置属性。

为了重用公共代码,您可以使用函数装饰器。在decorator函数中实现遍历树的公共代码,并在操作函数中对found元素执行操作。您可以按照以下方式更改代码:

def tree_operation(f):
    def recursive_wrapper(n, node):
       if node == None or node.data == n:
           # tree traversed to final point. do action for found element or
           # None
           return f(n, node)
       # try getting closer to interesting element
       elif node.data < n:
           return recursive_wrapper(n, node.right)
       else:
           return recursive_wrapper(n, node.left)
    return recursive_wrapper

@tree_operation
def search(n, node):
    if node == None:
        return False
    elif node.data == n:
        return True

@tree_operation
def insert(n, node):
    if node == None:
        # this obviously fail
        node.data = n
        node.left, node.right, node.middle = None
    elif node.data == n:
        insert(node.middle)

实际上它会传递函数,正如您所提到的那样,并将结果函数重命名为传入函数。 insert函数的上面装饰器语法执行此操作:

insert = tree_operation(insert)

答案 1 :(得分:0)

我认为最好不将函数的迭代部分组合在一起,因为它使代码复杂化。但是如果你认为迭代部分很复杂并且你需要编写一次,你可以重新考虑它如下:

def do_iterate(base_function, n, node=root):
    if node == None or node.data == n:
        base_function(n, node)
    elif node.data < n:
        do_iterate(base_function, n, node.right)
    else:
        do_iterate(base_function, n, node.left)

然后,您可以编写自己的base_function,当满足基本条件时将调用它。例如,您可以使用base_insert()和base_search()函数代替insert()和search()函数。

def base_insert(n, node):
    if node == None:
        node.data = n
        node.left, node.right, node.middle = None
    else:
        do_iterate(base_insert, n, node.middle)

def base_search(n, node):
    if node == None:
        return false
    else:
        return true

因此,您可以使用以下算法:

do_iterate(base_insert, 7)
do_iterate(base_search, 4)

最后,我不确定它比你的简单代码更好。