好的说我给了一个包含这个字母的对列表,它的频率 - 或者它在文本中看到的次数。 ex'((#\ a.4)(#\ b.2)(#\ c.9))如何找到2个最低频率,以便将它们组合成树?是否有某种功能可以帮助我找到这些?
答案 0 :(得分:3)
请查看§2.3.4一书中的SICP部分,在那里您可以找到有关如何从头开始实施霍夫曼编码树的完整说明。
关于这个问题,这里有一种可能的方法来找到具有指定格式的列表中的两个最低频率:
(define frequencies '((#\a . 4) (#\b . 2) (#\c . 9)))
(take
(sort frequencies
(lambda (x y)
(< (cdr x) (cdr y))))
2)
=> '((#\b . 2) (#\a . 4))
答案 1 :(得分:1)
仅使用未排序的频率列表表示可能不是解决此问题的正确方法。原因如下:重复查找最小值是计算霍夫曼编码树的主要操作。当你重复这个最小化操作时,你不想继续搜索整个列表。
作为针对该问题的第一次攻击:将排序视为一种方法,以便找到最小的快速操作。
但是,对于此特定问题,您应该考虑使用二进制heap,它是表示集合的数据结构。它具有非常酷的属性,将最小元素从堆中拉出来非常便宜。在Huffman树构建过程中,您将最终将新元素添加到您的集合中。你不想一遍又一遍地使用这个名单。
Racket在data/heap集合的标准库中实现了二进制堆。它对霍夫曼树构造的应用是相当简单的。下面用堆实现基本算法:
(require data/heap)
;; ...
;; make-huffman-tree: (listof leaf) -> node
(define (make-huffman-tree leaves)
(define a-heap (make-heap node<=?))
(heap-add-all! a-heap leaves)
(for ([i (in-range (sub1 (length leaves)))])
(define min-1 (heap-min a-heap))
(heap-remove-min! a-heap)
(define min-2 (heap-min a-heap))
(heap-remove-min! a-heap)
(heap-add! a-heap (merge (+ (frequency min-1) (frequency min-2))
min-1 min-2)))
(heap-min a-heap))
其中自由变量node<=?
旨在了解如何按频率进行比较,而merge
旨在采取两项措施并将它们组合在一起。
你可以在make-huffman-tree
中看到霍夫曼树构造的核心:使用堆来拉出两个最小元素,将它们合并在一起,然后将结果放回堆中。重复,直到我们留下一棵树。