1、哈夫曼树的概念
路径: 从一个结点到另一个结点之间的若干个分支
路径长度: 路径上的分支数目称为路径长度;
结点的路径长度: 从根到该结点的路径长度
树的路径长度: 树中所有叶子结点的路径长度之和;一般记为PL。
在结点数相同的条件下,完全二叉树是路径最短的二叉树。
上面的图中,1 ~ 5的路径长度为2, 1~8的路径长度为3
上面图中的左边的图的树的路径长度=2+3+3+2=10(相加的分别是4、7、8、6叶子结点的路径长度)
右边的图树的路径长度=3+2+2+2=9(相加的分别是8、5、6、7叶子结点的路径长度)
结点的权: 根据应用的需要可以给树的结点赋权值;
结点的带权路径长度: 从根到该结点的路径长度与该结点权的乘积;
树的带权路径长度 =树中所有叶子结点的带权路径之和;通常记作
WPL= w1 X L1+ …+ wi X Li (i=1,2,3,4,5…i)
哈夫曼树: 假设有n个权值(w1 , w2 , … , wn ),构造有n个叶子结点的二叉树,每个叶子结点有一个 wi 作为它的权值。则带权路径长度最小的二叉树称为哈夫曼树。
哈夫曼树只看叶子结点:
左图带权路径长度:27+25+22+24=36
右图带权路径长度:24+37+35+21=46
哈夫曼树的构建
想要构建一个哈夫曼树,那么需要树的带权路径最小,怎么才能让带权路径最小?
因为权值是不能发生改变的那么就让权值越大的数越靠近根结点,这样路径就短,带权路径长度也就越短
如何构建哈夫曼树?
所有叶子结点,都自成一棵树,构成一个二叉树的森林
从二叉树的深林中找权值最小的和次小的两棵二叉树,分别作为左右子数,构造一颗新的二叉树。
新的二叉树的根结点的权值为左右孩子权值之和
循环执行,直到森林中只剩下最后一颗二叉树
构造哈夫曼树的过程:
(1)将给定的n个权值{w1,w2,...,wn}作为n个根结点的权值构造一个具有n棵二叉树的森林{T1,T2,...,Tn},其中每棵二叉树只有一个根结点;
(2)在森林中选取两棵根结点权值最小的二叉树作为左右子树构造一棵新二叉树,新二叉树的根结点权值为这两棵树根的权值之和;
(3)在森林中,将上面选择的这两棵根权值最小的二叉树从森林中删除,并将刚刚新构造的二叉树加入到森林中;
(4)重复上面(2)和(3),直到森林中只有一棵二叉树为止。这棵二叉树就是哈夫曼树。
举个栗子:
构建哈夫曼树,每次都找最小的和次小的数构成一个新树
哈夫曼编码:
规定哈夫曼树中的左分支为0,右分支为1,则从根结点到每个叶结点所经过的分支对应的0和1组成的序列便为该结点对应字符的编码。这样的编码称为哈夫曼编码。
例如,左子树中的3的编码为:0000
左子树的11的编码为:001
右子树14编码为:110
在进行数据通讯时,涉及数据编码问题。所谓数据编码就是数据与二进制字符串的转换。
例如:邮局发电报:
前缀编码: 任何字符编码不是其它字符编码的前缀
设 A:0 B:110 C:10 D:111
发送方:将ABACCDA 转换成 0110010101110 总长度是13
所得的译码是唯一的
例 某通讯系统只使用8种字符a、b、c、d、e、f、g、h,其使用频率分别为0.05, 0.29, 0.07, 0.08, 0.14, 0.23, 0.03, 0.11,利用二叉树设计一种不等长编码,使得编码后的 二进制串总长最短。
构造以字符使用频率作为权值的哈夫曼树
WPL=(23+29)*2+(11+14)*3+(3+5+7+8)*4=271