有多种方法可以进行霍夫曼编码吗?

时间:2016-02-23 02:09:32

标签: haskell huffman-code

所以我制作了一个应该进行霍夫曼编码的程序。将我的答案与正确答案进行比较时,并非所有答案都匹配。

我得到了

[("a","0"),("c","100"),("b","101"),("d","110"),("f","1110"),("e","1111")]

正确的答案是

[('a',"0"),('b',"101"),('c',"100"),('d',"111"),('e',"1101"),('f',"1100")]

正确的树是 Correct Tree

然而,我的方法让我略有改变。在分支30上,我使用0来到D而不是1.

所以这让我想知道,这两个答案都是正确的吗?毕竟他们都有相同的字符串长度。

如果我错了,有人可以解释原因吗?

如果有人想要它,我的代码是用Haskell编写的

mergHufffman::(String,Int) -> (String,Int) -> (String,Int)
mergHufffman x y =  (fst x ++ fst y, snd x + snd y)

data HTree a = Leaf a | Branch (HTree a) (HTree a) deriving Show

treeHuff::[(String,Int)] -> HTree (String,Int)
treeHuff (x:[]) = Leaf x
treeHuff (x:y:[])
        | snd x < snd y = Branch (Leaf x) (Leaf y)
        | snd x > snd y = Branch (Leaf y) (Leaf x)
treeHuff (x:y:z:list)
        | snd x > snd merged = Branch (Leaf x) (treeHuff $ sortFirst $ y:z:list)
        | otherwise = Branch (treeHuff $ y:z:[]) (treeHuff $ sortFirst $ x:list)
        where merged = mergHufffman y z 

sortFirst::[(String,Int)]->[(String,Int)]
sortFirst freq = reverse $ sortBy (comparing snd) freq

readHuffTree :: HTree (String,Int)-> String -> [(String, String)]
readHuffTree (Branch x y) code = f1 ++ f2
                          where 
                          f1 = readHuffTree x (code ++ "0")
                          f2 = readHuffTree y (code ++ "1")
readHuffTree (Leaf x) code = ((fst x, code):[])

1 个答案:

答案 0 :(得分:6)

是的,您可以根据需要为左右分支分配0和1,并且您仍然拥有最佳的霍夫曼代码。两个答案都是正确的,除非赋值指定了如何将分配值分配给分支。事实上,有32个正确的答案,因为有五个分支,每个分支有两个选择。

当这些频率发生时,该树是唯一可能的树。但是,有一些频率可以使树具有不同的拓扑结构。

一个简单的例子是频率为1,1,2,2的频率。当您应用霍夫曼算法时,您会发现在第二步中选择两个最低频率时您可以选择做出任意选择。根据您所做的选择,最终会得到一个所有代码长度相同的树(2),或者最终会得到长度为1,2,3和3的代码。两个代码都是正确的答案。哦,对于1,2,3,3树,您可以选择频率为2的符号位于顶部。所以真的有三种不同的树是可能的。对于每棵树,您有八种方法来分配0和1。因此,在这种情况下有24个正确的答案。如果将代码长度乘以频率并将它们相加,您将看到两个树拓扑都给出12,因此两者都是最优的。