该题为2020年408真题,由题可知该编码为典型的哈夫曼编码。
在解该题之前,我们需要先回顾一下哈夫曼编码的特性。
一、什么是哈夫曼编码
哈夫曼编码是针对字符编码的一种可变长度编码,即允许对不同字符用不等长的二进制表示。不同使用频率的字符编码长度不同,由此可以起到压缩数据的效果。为避免歧义,对哈夫曼编码采取前缀编码操作(没有一个编码是另一个编码的前缀),即所有字符都必须是叶子结点。
二、判定字符集的不等长编码是否具有前缀特性的过程
事先我们不知道该字符集的对应的二叉树,因此判定编码是否具有前缀特性的过程就是构建二叉树的过程。
初始时,二叉树中仅含有根结点,其左子指针和右子指针均为空。
依次读入每个编码 C,建立/寻找从根开始对应于该编码的一条路径,过程如下:
对每个编码,从左至右扫描C的各位,根据C的当前位(0或1)沿结点的指针(左子指针或右子指针)向下移动。当遇到空指针时,创建新结点,让空指针指向该新结点并继续移动。沿指针移动的过程中,可能遇到三种情况:
1. 若遇到了叶结点(非根),则表明不具有前缀特性,返回。上文中说到每个字符都位于二叉树的叶结点,当编码c在指针移动过程中遇到了叶结点,此时说明编码c对应的字符是某个字符的子孙,这样就会造成一个编码是另一个编码的前缀,不满足前缀特性。
例如,设左分支为0,右分支为1,编码c为101,对应下图我们可以发现要想继续查找,就需要在a结点下继续创建子结点,但这就不满足前缀特性。
2. 若在处理C的所有位的过程中,均没有创建新结点,则表明不具有前缀特性,返回。
再以上图为例,设编码c为000,那么指针移动时就会发现,当c的所有位都处理完毕后,仍然没有创建一个新结点,此时说明该字符集中有不同字符对应的编码相同,此时也不满足前缀特性,返回。
3. 若在处理C的最后一个编码位时创建了新结点,则继续验证下一个编码。
若所有编码均通过验证,则编码具有前缀特性。