Haskell 建树

Haskell 建树,haskell,tree,binary-tree,huffman-code,algebraic-data-types,Haskell,Tree,Binary Tree,Huffman Code,Algebraic Data Types,我有一棵哈夫曼树,它是用来编码字符串的。我已经定义了功能plant,但我不确定我的树是否只向一侧倾斜过多。这是我的密码: data HuffTree = Leaf Char | HuffTree |*| HuffTree deriving (Eq, Show) *是一个中缀构造函数 plant :: [(Char,Int)] -> HuffTree plant [(x,y)] = (Leaf x) plant ((x,y):xs) = plant xs

我有一棵哈夫曼树,它是用来编码字符串的。我已经定义了功能
plant
,但我不确定我的树是否只向一侧倾斜过多。这是我的密码:

data HuffTree
    = Leaf Char
    | HuffTree |*| HuffTree     
    deriving (Eq, Show)
*
是一个中缀构造函数

plant :: [(Char,Int)] -> HuffTree
plant [(x,y)] = (Leaf x)
plant ((x,y):xs) = plant xs |*| (Leaf x) 

对我来说,它看起来是片面的,因此它实际上并不意味着编码思想,因为它不是一个真正的二叉树。我怎样才能把它变成一个普通的二叉树呢

您没有正确构建哈夫曼树。这个过程应该是这样的:

  • 将所有源符号转换为单元素哈夫曼树
  • 将每个源符号与其频率配对,形成一个大的树/频率对列表
  • 如果只剩下一个树/频率对,那么这棵树就是你的哈夫曼树
  • 否则,删除频率最低的两个树/频率对,合并树并添加频率以创建新的树/频率对,然后将其添加回列表
  • 转到3

  • 所以我把它改成
    plant::[(HuffTree,Int)]->HuffTree
    。在第二种情况下,我会对元素进行排序,去掉前两个元素,组合它们,然后递归调用
    plant
    。您可能还希望切换到
    (Int,HuffTree)
    对,以便使用默认的排序实现。您还需要将
    Ord
    添加到
    HuffTree
    派生子句中。

    您没有正确构造Huffman树。这个过程应该是这样的:

  • 将所有源符号转换为单元素哈夫曼树
  • 将每个源符号与其频率配对,形成一个大的树/频率对列表
  • 如果只剩下一个树/频率对,那么这棵树就是你的哈夫曼树
  • 否则,删除频率最低的两个树/频率对,合并树并添加频率以创建新的树/频率对,然后将其添加回列表
  • 转到3

  • 所以我把它改成
    plant::[(HuffTree,Int)]->HuffTree
    。在第二种情况下,我会对元素进行排序,去掉前两个元素,组合它们,然后递归调用
    plant
    。您可能还希望切换到
    (Int,HuffTree)
    对,以便使用默认的排序实现。您还需要将
    Ord
    添加到
    HuffTree
    派生子句中。

    您的数据类型实际上不适合表示Huffman树,因为您不在任何地方存储频率。频率可以隐含在节点上(这是低效的),但必须在叶子上有频率。您的数据类型并不真正适合表示哈夫曼树,因为您不在任何地方存储频率。节点处的频率可以是隐式的(这是低效的),但必须在叶子处具有该频率。