Python使用递归查找树的路径

时间:2017-04-26 15:20:09

标签: python recursion tree return path-finding

我一直在尝试实现基于数字的霍夫曼编码算法。我已经完成了构建霍夫曼树的部分。但递归算法并没有按预期工作。它应该将树中的路径从根返回到指定节点,但它总是返回错误的路径。

奇怪的是,代码似乎正在做正确的事情,它可以找到真正的路径。但它返回的结果总是别的。

def get_encoding_for(symbol_p, node, encoding):
    global encoded_string
    result = encoding
    if not isinstance(node, list):
        if symbol_p == node:
            encoded_string = result
            return result
    else:
        for n in node:
            index = str(node.index(n))
            # print("Node {} with index {}".format(n, index))
            result = get_encoding_for(symbol_p, n, encoding + index)

    return result

使用简单的列表构建树。

The huffman tree looks like: [[3.0, [1.0, 2.0]], [4.0, 5.0]]

这是使用元素1,2,3,4,5的简单树的示例输出。

Loop 1.0. Node 1.0 -> Coding 010:
Loop 2.0. Node 2.0 -> Coding 011:
Loop 3.0. Node 3.0 -> Coding 00:
Loop 4.0. Node 4.0 -> Coding 10:
Loop 5.0. Node 5.0 -> Coding 11:

这就是我希望函数返回的内容,但它只返回我" 11"在所有五次迭代中。我不得不使用全局变量来拦截"正确的编码,我对此不满意......我认为问题在于回归。我已经尝试了很多回归的方法,但没有一种方法能够奏效。

有人能告诉我递归的错误吗?非常感谢你!

2 个答案:

答案 0 :(得分:0)

在树中搜索一个项目有点棘手。递归完成后,返回需要指示成功(再次返回)或失败(再次递归)。迭代完成,返回很容易,但需要显式堆栈的可能搜索位置。以下是前者,利用了树的二进制结构。注1:我使用的名称使 me 更容易正确地编写。他们不一定“更好”。注2:我在测试中添加了“未找到”的案例。

def encoding(char, bintree, path):
    if isinstance(bintree, list):
        p = encoding(char, bintree[0], path+'0')
        if p:
            return p
        return encoding(char, bintree[1], path+'1')
    else:
        return path if char == bintree else ''

# Test
hufftree = [[3, [1, 2]], [4, 5]]
for i in range(6):
    print(encoding(i, hufftree, ''))
# Prints

010
011
00
10
11

答案 1 :(得分:0)

另一种方法(与我的第一个答案中的方法不同)是将生成路径与停止逻辑分开。

def paths(bintree):
    if isinstance(bintree, list):
        for i, p in ((0,'0'), (1,'1')):
            for val, path in paths(bintree[i]):
                yield (val, p + path)
    else:
        yield (bintree, '')

def encoding2(i, bintree):
    for val, path in paths(hufftree):
        if i == val:
            return path
    return ''

# Test
hufftree = [[3, [1, 2]], [4, 5]]
for v in paths(hufftree): print(v)
for i in range(6):
    print(encoding2(i, hufftree))
# Prints

010
011
00
10
11

此时,人们可能会考虑创建一个dict映射值来编码。

huffdict = dict(paths(hufftree))
for i in range(6):
    print(huffdict.get(i, ''))
# Prints same as above