OK,昨天我们对huffman数的基本知识,以及huffman树的创建做了一些简介,http://www.cnblogs.com/Frank-C/p/5017430.html

今天接着聊:

huffman树创建完成之后,我们如何去得到huffman编码呢?

图12.4_1 huffman树形结构

图12.4_2  huffman存储结构(数组)

首先,以上面的树为例,我们必须明白几个要点:

1:从什么地方开始访问这颗树:根节点 , index 2n-1 = 15

2:访问的规则:向左为0  向右为1

3:以什么样的访问循序去访问呢?

好说,

(1): 询问是否有左孩子,一直向左走,直到左孩子为零,如果此时右孩子也为零,证明已经找到了一个叶子结点(信息元)。(当然,在访问的同时进行编码记录)

(2): 原路返回一层(编码同时减一),询问是否有右孩子,有,进入右孩子,无,再返回上一层

一直重复(1)和(2)步,直到最终回退到更节点,在回到根节点的parent,即此时迭代器(index)为零

当然,我只是说了一下大概的步骤,具体的代码实现,还得是细之又细,往下看!!!!!!   有木有

*HC=(HuffmanCode)malloc((n+)*sizeof(char*));
/* 分配n个字符编码的头指针向量([0]不用) */
cd=(char*)malloc(n*sizeof(char)); /* 分配求编码的工作空间 即传递(temp)空间*/
c=m; //直接指向最上面那个非叶子节点
cdlen=;
for(i=;i<=m;++i)/* 遍历赫夫曼树时用作结点状态标志 直接把全部节点置为零 此时这棵树已经建立了 故权重已经没有多大用处了*/
(*HT)[i].weight=;
while(c)
{
if((*HT)[c].weight==) //负责向左
{ /* 向左 */
(*HT)[c].weight=; /* ************* */
if((*HT)[c].lchild!=) /*如果权为零的左孩子节点不是第一个元素(下标为0)*/
{
c=(*HT)[c].lchild;
cd[cdlen++]='';
}
/*看这个左孩子有没有右孩子 如果右孩子为零(即没有右孩子),那么是一个叶子节点*/
else if((*HT)[c].rchild==)
{ /* 登记叶子结点的字符的编码 */
(*HC)[c]=(char *)malloc((cdlen+)*sizeof(char));
cd[cdlen]='\0';
strcpy((*HC)[c],cd); /* 复制编码(串) */
}
}
/*条件改变*/
else if((*HT)[c].weight==) /*负责向右 只会回退 不会动 判断是左孩子是叶子节点还是中间的内点*/
{ /* 向右 */
(*HT)[c].weight=; /////************
if((*HT)[c].rchild!=) //决定你这个权值此时会不会被清零
{
c=(*HT)[c].rchild;
cd[cdlen++]='';
}
}
else //负责回退
{ /* HT[c].weight==2,退回 */
(*HT)[c].weight=; /////**************
c=(*HT)[c].parent;
--cdlen; /* 退到父结点,编码长度减1 迭代:利用前面走过的路*/
}
}
free(cd);

上面代码通过一个weight(在while语句执行之前就已经被清零了哦哦哦),来判断当前节点(叶子节点的情况除外):(只作为过程说明,不是状态判断条件)

未被访问或已经被访问且没有用了:  0

正在访问左树且“右树还没有访问”(当然这是废话): 1

正在访问右树且 ”左树已经访问“  (当然这也是废话): 2

什么时候回退,左节点没有或已经访问完,且,右节点没有或已经访问玩,如何保证之前这些个条件呢。简单,if else分支语句的作用体现出来了,把负责回退的判断语句放在最后,前面来判断有左孩子木有哈,有右孩子木有啊,没有,证明找到一个叶子节点(信息元),记录信息,此时,此叶子节点weight已经被置为1,那么最中被置为2且没有右节点,进入最后一个else分支,置为零且回退。

当分支节点为1是(此时左节点已经被访问),会首先被置为2,询问是否有右节点,有进入,即注意,当前节点如果是父节点的右孩子,字此时的父节点weight定被置为了二,当此节点为叶子节点且符合上面的叶子节点回退规则时,回退到父节点,父节点有为2,继续回退。

总结:代码分支语句分成了三个主分支块   weight为0(判断是否未访问过的节点)     weight为1(判断是否为左树已经访问)    weight为2,节点weight需要进行清零且回退

对于叶子节点,则主要有第一个分支块进行处理,并由第二和三个分支块进行辅助判断与回退。

如何去通过编码反编译成信息或信息元,我想着就再简单不过了,至少比编码的创建容易吧,直接根据树以一定的规则去找(如,0:左孩子, 1:右孩子),  鉴于每个信息元的独立性与信息元之间的无包含性,既适合反编码,有适合找错误。

OK,That’s  all!!!

Huffman树与最优二叉树续的更多相关文章

  1. 数据结构之Huffman树与最优二叉树

    最近在翻炒一些关于树的知识,发现一个比较有意思的二叉树,huffman树,对应到离散数学中的一种名为最优二叉树的路径结构,而Huffman的主要作用,最终可以归结到一种名为huffman编码的编码方式 ...

  2. 数据结构-二叉树(6)哈夫曼树(Huffman树)/最优二叉树

    树的路径长度是从树根到每一个结点的路径长度(经过的边数)之和. n个结点的一般二叉树,为完全二叉树时取最小路径长度PL=0+1+1+2+2+2+2+… 带权路径长度=根结点到任意结点的路径长度*该结点 ...

  3. 哈夫曼树【最优二叉树】【Huffman】

    [转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树:         在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设 ...

  4. 数据结构与算法(周鹏-未出版)-第六章 树-6.5 Huffman 树

    6.5 Huffman 树 Huffman 树又称最优树,可以用来构造最优编码,用于信息传输.数据压缩等方面,是一类有着广泛应用的二叉树. 6.5.1 二叉编码树 在计算机系统中,符号数据在处理之前首 ...

  5. [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. HUFFMAN 树

    在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么 ...

  7. Huffman树及其应用

    哈夫曼树又称为最优二叉树,哈夫曼树的一个最主要的应用就是哈夫曼编码,本文通过简单的问题举例阐释哈夫曼编码的由来,并用哈夫曼树的方法构造哈夫曼编码,最终解决问题来更好的认识哈夫曼树的应用--哈夫曼编码. ...

  8. Huffman树的构造及编码与译码的实现

    哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...

  9. Java---Huffman树的实现

    什么是哈弗曼树 1.哈弗曼树是最优二叉树,树的带权路径长度最小的一个二叉树. 2.带权路径长度为根节点到该节点的路径长度和该节点权重的乘积.3.路径长度为当前节点到另一个节点所经过的分支的个数(边的个 ...

随机推荐

  1. Java 将字节数组转化为16进制的多种方案

    很多时候我们需要将字节数组转化为16进制字符串来保存,尤其在很多加密的场景中,例如保存密钥等.因为字节数组,除了写入文件或者以二进制的形式写入数据库以外,无法直接转为为字符串,因为字符串结尾有\0,当 ...

  2. JSP中的include有哪些?有什么差别?

    JSP中的include有哪些?有什么差别? 1.JSP中的include有哪些 (1)<%@include file="" %> (2)<jsp:include ...

  3. socket计划编制的原则

    socket编程原理 1.问题的引入 1) 普通的I/O操作过程: UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-rea ...

  4. 【C语言】推断一个数的奇偶(位操作)

    //推断一个数的奇偶 #include <stdio.h> int is_signal(int num) { if (num & 1) return 1; else return ...

  5. Python 显示LinkedIn用户作业

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-8-18 @author: guaguastd @name: j ...

  6. 非常棒的Visual Studo调试插件:OzCode 2.0 下载地址

    最新版下载地址 http://download.csdn.net/detail/simadi/8925511 如果你是一名C#开发者,那么,你则需要OzCode.它将可视化调试的概念上升到了一个新的高 ...

  7. 使用jquery点击一个实现button或连接,进行以下div显示,在点击隐藏

    jquery代码: <script type="text/javascript" src="js/jquery-1.7.2.js"></scr ...

  8. 字符串查找KMP算法(转)

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  9. iOS开发:多线程技术概述

    一.概述 线程(thread):用于指代独立执行的代码段. 进程(process):用于指代一个正在运行的可执行程序,它可以包含多个线程. 任务(task):用于指代抽象的概念,表示需要执行工作. 多 ...

  10. 基本数据类型TypeScript

    TypeScript 前言 最近项目很急,所以没有什么时间回答关于Xamarin.Android方面的问题,也有一段时间没有更新.主要是手头很缺人,如果有谁有兴趣加入我们的话,可以私聊我,这样我就能继 ...