Huffman编码

以下是SICP关于Huffman编码的描述:

一个Huffman编码可以表示为一棵二叉树,其中的树叶是被编码的符号。树中每个非叶结点代表一个集合,其中包含了这一结点之下的所有树叶上的符号。除此之外,位于树叶的每个符号还被赋予一个权重(也就是它的相对频度),非叶结点所包含的权重是位于它之下的所有叶结点的权重之和。

以下是一个示例:

代码示例

将书中代码转换成common lisp:

;;将一棵树表示为包含符号leaf,叶中符号和权重的表
(defun make-leaf (symb weight)(list 'leaf symb weight))
;;判断是否是叶子
(defun leafp (obj)(equal (car obj) 'leaf))
;;取出叶中符号
(defun symbol-leaf (x) (cadr x))
;;取出叶中权重
(defun weight-leaf (x) (caddr x))
;;选择函数:左枝
(defun left-branch (tree) (car tree))
;;选择函数:右枝
(defun right-branch (tree) (cadr tree))
;;取出结点的符号集合,即这一结点之下所有树叶的符号
(defun symbols (tree)(if (leafp tree)(list (symbol-leaf tree))(caddr tree)))
;;取出结点的权重,即其下所有树叶权重之和
(defun weight (tree)(if (leafp tree)(weight-leaf tree)(cadddr tree)))
;;归并两个结点做出一棵树,将符号取并集,权重相加
(defun make-code-tree (left right)(list leftright(append (symbols left) (symbols right))(+ (weight left) (weight right))))
;;bits是二进制位的表,调用选择函数,一但到达叶结点,即把此处的符号加入到随后的解码结果
(defun decode (bits tree)(defun decode-1 (bits current-branch)(if (null bit)'()(let ((next-branch (choose-branch (car bits) current-branch)))(if (leafp next-branch)(cons (symbol-leaf next-branch)(decode-1 (cdr bits) tree))(decode-1 (cdr bits) next-branch)))))(decode-1 bits tree))
;;选择分支函数,根据是0还是1选择树的左分支或右分支
(defun choose-branch (bit branch)(cond ((= bit 0) (left-branch branch))((= bit 1) (right-branch branch))(t (error "bad bit --CHOOSE-BRANCH"))))
;;将树叶和树的集合表示为元素的表,这里我按照权重下降顺序排列(和书中不同)
(defun adjoin-set (x set)(cond ((null set) (list x))((> (weight x) (weight (car set)))(cons x set))(t (cons (car set)(adjoin-set x (cdr set))))))
;;以一个符号-权重表为参数,构造出树叶的初始排序集合
(defun make-leaf-set (pairs)(if (null pairs)'()(let ((pair (car pairs)))(adjoin-set (make-leaf (car pair) (cadr pair))(make-leaf-set (cdr pairs))))))

下面是练习2.67,2.68,2.69的实现:

;;译码,由给定符号串译成二进制数
(defun encode (message tree)(if (null message)'()(append (encode-symbol (car message) tree)(encode (cdr message) tree))))
;;将给定字符译码
(defun encode-symbol (char tree)(defun find-in (x lst)(if (null lst)nil(or (equal x (car lst))(find-in x (cdr lst)))))(defun encode-iter (char tree)(if (leafp tree)'()(if (find-in char (symbols (left-branch tree)))(append (list 0) (encode-iter char (left-branch tree)))(append (list 1) (encode-iter char (right-branch tree))))))(if (find-in char (symbols tree))(encode-iter char tree)(error "No such element")))
;;由符号-频度对偶表生成编码树
(defun generate-huffman-tree (pairs)(successive-merge (make-leaf-set pairs)))
;;反复归并集合
(defun successive-merge (lst)(if (null (cdr lst))(car lst)(make-code-tree (car lst)(successive-merge (cdr lst)))))
;;示例树
(setf sample-tree(make-code-tree (make-leaf 'a 4)(make-code-tree(make-leaf 'b 2)(make-code-tree (make-leaf 'd 1)(make-leaf 'c 1)))))
;;示例消息,待解码
(setf sample-message '(0 1 1 0 0 1 0 1 0 1 1 1 0))
;;示例符号-权重对偶表
(setf sample-pairs '((a 4) (b 2) (c 1) (d 1)))

运行结果(lispbox-0.7):

SICP-Huffman相关推荐

  1. SICP读书笔记 2.3

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  2. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  3. huffman树和huffman编码

    不知道为什么,我写的代码都是又臭又长. 直接上代码: #include <iostream> #include <cstdarg> using namespace std; c ...

  4. 技术图文:如何利用C#实现Huffman编码?

    背景 Huffman编码 在通信和数据压缩领域具有重要的应用. 在介绍 Huffman 编码具体实现之前,先介绍几个相关的概念. 概念1:树中结点的带权路径长度 – 根结点到该结点的路径长度与该结点权 ...

  5. huffman java_详解Huffman编码算法之Java实现

    Huffman编码介绍 Huffman编码处理的是字符以及字符对应的二进制的编码配对问题,分为编码和解码,目的是压缩字符对应的二进制数据长度.我们知道字符存贮和传输的时候都是二进制的(计算机只认识0/ ...

  6. csapp 、sicp 、深入理解计算机系统、 计算机程序的构造和解释

    CSAPP 第一版的英文版 深入理解计算机系统第一版中文版  这个是csdn账号  这里上传文件大小在10M以内  这个pdf是19+M的 深入理解计算机系统第二版的中文版下载 第一版英文版的介绍原书 ...

  7. SICP 习题 (2.7) 解题总结 : 定义区间数据结构

    SICP 习题 2.7 開始属于扩展练习,能够考虑不做,对后面的学习没什么影响.只是,假设上面的使用过程表示序对,还有丘奇计数你都能够理解的话,完毕这些扩展练习事实上没什么问题. 习题2.7是要求我们 ...

  8. Huffman 编码压缩算法

    为什么80%的码农都做不了架构师?>>>    前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 David Huf ...

  9. 奇妙的二叉树:Huffman的贡献

      提起 Huffman 这个名字,程序员们至少会联想到二叉树和二进制编码.的确,我们总以 Huffman 编码来概括 D.A.Huffman 个人对计算机领域特别是数据压缩领域的杰出贡献.我们知道, ...

  10. java 实现部门树_(java实现)哈夫曼(Huffman)树编码(自编压缩项目基础)

    哈夫曼树 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树, 若该树的带权路径长度(wpl) 达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 也叫霍夫曼树. 哈 ...

最新文章

  1. hbase shell 查看列名_Hbase的简单命令使用
  2. matlab文档型数据导入,MATLAB-数据导入
  3. 19元素的显示与隐藏
  4. 手机项目,html抬头,HTMLCSS学习笔记(二十)-- 移动端项目准备工作
  5. Redis源码剖析(六)事务模块
  6. rfid技术及应用答案王佳斌_详解工业数据采集中RFID技术的应用
  7. (1) IFC格式简介 (Industry Foundation Class)
  8. 射频放大电路的优化及ADS仿真
  9. 第三方支付,微信支付及支付宝的一些入门了解
  10. 一条让人不安的坐地龙
  11. STM32/KEIL/MDK 查看 FLASH 和 RAM 使用情况
  12. 重装mac系统 未能与恢复服务器取得联系,进入 macOS 系统恢复模式 – 重新安装 macOS 系统...
  13. Win10 时间与Internet时间同步超时
  14. 关于pend post 与 accept
  15. 基于知识图谱的表示学习——Trans系列算法介绍(一)
  16. 沃信科技T3 Sota安装配置手册(1-4章)
  17. 神经网络 深度神经网络,最新的深度神经网络
  18. C++11条件变量:notify_one()与notify_all()的区别
  19. 金蝶KIS记账王光盘版 双12五折特惠
  20. 大唐杯学习笔记(1)---5G网络架构和组网部署

热门文章

  1. 笔记本开热点,手机无法连接
  2. Python摄氏度与华氏度的计算
  3. python choice金融终端_django choice字段模板展示
  4. 使用Camstudio和KeyCastOW来录屏制作软件Demo视频
  5. 一次 MySQL 老数据同步
  6. iOS 下载功能(断点续传)
  7. 麒麟970和骁龙710
  8. UDE上的这家潮电街区,惊艳了整个展会
  9. qq空间h5页面,如何在微信中直接打开qq空间链接却不需要登陆qq账号密码
  10. stm32f030c8之基础定时器TIM6