如何在搜索特定元素时递归遍历霍夫曼树? - C

时间:2015-12-22 01:07:45

标签: c recursion huffman-code

我正在使用霍夫曼代码,我目前处于将文本文件编码/解码为二进制文件的阶段。我有这段代码从树中检索节点及其所有相关数据(字符,频率,路由):

EmptyString ( string );
while ( ( c = fgetc ( nameTextFile ) ) != EOF ) {
    nodeHuffmanTree = SearchHuffmanTree ( rootHuffmanTree, c );
    strcpy ( string, nodeHuffmanTree -> route );
    Encode ( nameBinaryFile, string );
    EmptyString ( string );
}

假设已经生成了每个节点(0' s和1' s)的路由。我想要的 SearchHuffmanTree 函数是,给定一个字符,它在Huffman树中搜索所述字符,它返回包含它的节点。这是相关的,因为该节点将包含 Encode 函数将转换为字节的路径。

我知道我不能像二进制搜索树一样对待霍夫曼树,因为它没有共享相同的特征,所以如果我想搜索一个特定的角色,我将不得不穿过整棵树。

我已经在不使用递归(以及某些堆栈)的情况下寻找替代方案,并且虽然它们更易于理解,但它们产生的简单和干净的代码却相当简单,所以我更喜欢使用解决方案递归。

我已经找到了编码/解码部分,所以这几乎是最终完成代码的最后一步。期待您的帮助,您可以给我。

1 个答案:

答案 0 :(得分:0)

是的,您不能假设树中任何特定节点(即字符)的位置,因为节点的位置取决于字符的频率而不是它们的值。因此,您必须找到一种遍历整棵树的方法,而不做任何假设。

通常有两种遍历图形的方法:广度优先搜索(BFS),它基于队列,深度优先搜索(DFS),基于堆栈。

由于DFS基于堆栈,因此它本身就是递归问题。此外,由于2种方法穿越树的方式不同,在您的情况下,DFS的平均效率会更高。

DFS如何运作?

嗯,基本原则是如果节点不是叶子,则在每个子节点上执行DFS。如果选择遍历子树的顺序,则可以先获取最高概率路径,这样可以更快地找到结果。

下面是算法的简单伪代码:

DFS(node T, char x) {
    if (T is leaf)
        if (T == x)
            return found
        else
            return not found
    else
        foreach child of T
            if DFS(child, x) == found
                return found
        return not found

您可以在DFS的维基百科页面上找到更多详细信息。