当前位置: 首页 > news >正文

山西太原做企业网站建设的公司/广州网络推广服务商

山西太原做企业网站建设的公司,广州网络推广服务商,口碑好网站建设哪家好,有道云笔记做网站文章目录哈夫曼树(最优二叉树)哈夫曼树构造算法哈夫曼构造算法的实现哈夫曼编码文件的编码和译码哈夫曼树(最优二叉树) 定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为…

文章目录

  • 哈夫曼树(最优二叉树)
  • 哈夫曼树构造算法
    • 哈夫曼构造算法的实现
  • 哈夫曼编码
    • 文件的编码和译码

哈夫曼树(最优二叉树)

定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

路径:从树中一个结点到另一个结点之间得分支构成这两个结点间的路径。
结点的路径长度:两结点间路径上的分支数
树的路径长度:树根到每一个结点的路径长度之和。记作:TL

结点数目相同的二叉树中,完全二叉树是路径长度最短的二叉树

权(weight):将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权
结点的带权路径长度:结点到该结点之间的路径长度与该结点的乘积
树的带权路径长度:树中所有叶子结点的带权路径长度之和
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为构造这种树的算法是由哈夫曼教授于1952年提出的,所以被称为哈夫曼树,相应的算法称为哈夫曼算法

  • 1.满二叉树不一定是哈夫曼树
    2.哈夫曼树中权越大的叶子离根越近
    3.具有相同带权结点的哈夫曼树不唯一

哈夫曼树构造算法

哈夫曼算法:
1.根据 n 个给定的权值{W1,W2,…,Wn}构成 n 棵二叉树的森林 F={T1,T2,…,Tn},其中 Ti 只有一个带权为 Wi 的根结点

  • 构造森林全是根

2.在F中选取两棵根结点的权值最小的数作为左右子树,构造一棵新的二叉树,且设置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。

  • 选用两小造新树

3.在 F 中删除这两棵树,同时将新得到的二叉树加入森林中

  • 删除两小添新人

4.重复②和③,直到森林中只有一棵树为止,这棵树即为哈夫曼树

  • 重复2、3单根

哈夫曼算法口诀:
1.构造森林全是根;
2.选用两小造新树;
3.删除两小添新人;
4.重复2、3剩单根。

下面给个例子:
在这里插入图片描述
特点:
1.包含n个叶子结点的哈夫曼树中共有2n-1个结点
2.哈夫曼树的结点的度数为0或2,没有度为1的结点。
3.包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个新结点
在这里插入图片描述
总结:
1、在哈夫曼算法中,初始时有 n 棵二叉树,要经过n-1次合并最终形成哈夫曼树
2、经过 n-1 次合并产生 n-1 个新结点,且这 n-1 个新结点都是具有两个孩子的分支结点
可见,哈夫曼树中共有n+n-1 = 2n - 1个结点,且其所有的分支结点的度均不为1。

哈夫曼构造算法的实现

①我们采用顺序存储结构——一维结构数组
②结点类型定义

typedef struct
{int weight;int parent,lch,rch;
}HTNode,*HuffmanTree;  定义数组 HuffmanTree H;

例,有n = 8,权值为W={7,19,2,6,32,3,21,10},构造哈夫曼树
在这里插入图片描述
【步骤】

  1. 初始化 HT[1…2n-1] :lch=rch=parent=0;
  2. 输入初始 n 个叶子结点:置 HT[1…n]的weight值
    (HT就是上图左边的结构数组)
  3. 进行以下n-1次合并,依次产生n-1次个结点HT[i],i=n+1…2n-1:
    a)在HT[1…i-1]中选两个未被选过(从parent==0的结点中选)的weight最小的两个结点HT[s1]HT[s2],s1、s2为两个最小结点下标
    b)修改HT[s1]和HT[s2]的parent值 :HT[s1].parent = i;HT[s2].parent = i;
    c)修改新产生的HT[i]:
    • HT[i].weight = HT[s1].weight + HT[s2].weight;
    • HT[i].lch = s1; HT[i].rch =s2;
void CreateHuffmanTree(HuffmanTree &HT,int n)//构造哈夫曼树HT
{if(n<=1) return;m = 2*n - 1; //数组共2n-1个元素 HT = new HTNode[2*n];  //0号单元未用,HT[m]表示根结点 for(int i = 1; i <= m; ++i)  //将2n-1个元素的 lch、rch、parent置为0 {HT[i].parent = 0;HT[i].lchild = 0;HT[i].rchild = 0;}for(int i =1; i <= n ; ++i) //输入前n个元素的weight值 {cin >> HT[i].weight;}/* ---初始化结束,下面开始建立哈夫曼树---  */ for(int i = n + 1; i <= m; ++i)  //合并产生n-1个结点——构造Huffman树 {int s1,s2;select(HT,i-1, s1, s2);  //在HT[k](1≤k ≤i-1)中选择两个其双亲域为0,//且权值最小的结点,并返回它们在HT中的序号s1和s2							 HT[s1].parent = i;      HT[s2].parent = i;      //表示从F中删除s1,s2HT[i].lchild = s1;HT[i].rchild = s2;      //s1,s2分别作为i的左右孩子 HT[i].weight = HT[s1].weight + HT[s2].weight;	//i的权值为左右孩子权值之和 }	
}

哈夫曼编码

哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

怎么样的前缀码能使得电文总长最短?哈夫曼编码
方法:

  1. 统计字符集中每个字符在电文中出现的平均概率(概率越大,要求编码越短)。
  2. 利用哈夫曼树得特点:权越大得叶子离根越近;将每个字符得概率值最为权值,构造哈夫曼树。则概率越大的结点,路径越短。
  3. 在哈夫曼树的每个分支上标上0或1:
    结点的左分支标0,右分支标1
    把从根到每个叶子的路径上的标号连接起来,作为该叶子代表的字符的编码。

在这里插入图片描述
两个问题:

  1. 为什么哈夫曼编码能够保证是前缀编码?
    答:因为没有一片树叶是另一片树叶的祖先,所以每个叶结点的编码就不可能是其他叶结点编码的前缀

  2. 为什么哈夫曼树编码能够保证字符编码总长最短?
    答:因为哈夫曼树的带权路径最短,故字符编码的总长最短
    性质1:哈夫曼编码是前缀码
    性质2:哈夫曼编码是最优前缀码

void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{  //从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中 HC = new char*[n+1];         //分配n个字符编码的头指针矢量 char *cd = new char[n];      //分配临时存放的编码的动态数组空间 cd[n-1]='\0';                //编码结束符 for(int i = 1;i <= n ;i++)   //逐个字符求哈夫曼编码 {int start = n-1;int c =i;int f = HT[i].parent;while(f!=0)              //从叶子节点开始向上回溯,直到根结点 {--start;             //回溯一次start向前一个位置 if(HT[f].lchild == c) cd[start] ='0';  //结点c是f的左孩子,则生成代码0 else cd[start] ='1';    //结点c是f的右孩子,则生成代码1 c = f;f =HT[f].parent;  //继续向上回溯 }                           //求出第i个字符的编码 HC[i] =new char[n-start];   //为第i个字符串编码分配空间 strcpy(HC[i], &cd[start]);  // 将求得的编码从临时空间cd复制到HC的当前中 }delete cd;                      //释放临时空间 
}

文件的编码和译码

  1. 编码:
    ① 输入各字符及其权值
    ② 构造哈夫曼树——HT[i]
    ③ 进行哈夫曼编码——HC[i]
    ④ 查 HC[i],得到各字符的哈夫曼编码

  2. 解码:
    ① 构造哈夫曼树
    ② 依次读入二进制码
    ③ 读入0,则走向左孩子;读入1,则走向右孩子
    ④ 一旦到达某叶子时,即可译出字符
    ⑤ 然后再从根出发继续译码

在这里插入图片描述


学习笔记内容来自:青岛大学——王卓老师

http://www.lbrq.cn/news/1380511.html

相关文章:

  • 做农药的网站/怎样注册一个自己的平台
  • 烟台做网站优化/百度推广首页登录
  • java和PHP做网站哪个好6/怎么推广一个app
  • 个人网站建设模板下载/嘉兴网站建设制作
  • 安全无毒做网站/平台优化是什么意思
  • 西安百度推广服务公司/seo排名是什么意思
  • 哈尔滨网站制作建设多少钱/结构优化
  • 四川建设厅特种工报名网站/seo创业
  • 企业园区网络设计方案/站长工具seo排名查询
  • 毕业设计网站代做靠谱吗/搜索量最大的关键词
  • 做装修有什么好网站可以做/网页制作网站
  • wordpress更新要ftp/赣州seo外包怎么收费
  • 福州做网站的公/友情链接网站免费
  • 东莞建站/外链发布软件
  • ui培训哪里好/蜗牛精灵seo
  • 网页设计和网站建设是同一回事吗/湖南疫情最新情况
  • 教做黏土手工的网站/湘潭seo优化
  • 做网站千篇一律/关键词推广操作
  • 我要用新浪云做网站/北京网站优化经理
  • 成都专业网站推广/seo排名优化培训怎样
  • 做网站属软件什么专业/广告公司名称
  • 重庆微信网站制作专家/百度指数的搜索指数
  • 程序员自己做网站赚钱/如何创建网址
  • 上海门户网站制作/企业如何进行搜索引擎优化
  • 网站怎么做视频背景/深圳推广
  • 湘西 网站 建设 公司/东莞整站优化推广公司找火速
  • 二级网站怎样做排名/企业网站免费制作
  • 云主机可以做网站吗/扬州网络推广公司
  • 石桥铺网站建设公司/千锋培训学费多少钱
  • 瓷器网站怎么做/品牌宣传推广策划方案
  • (27)运动目标检测之对二维点集进行卡尔曼滤波
  • 每日算法刷题Day56:7.31:leetcode 栈6道题,用时2h30min
  • 机器学习基础-seaborn
  • Kafka Streams窗口技术全解析:从理论到电商实时分析实战
  • 计算机网络基础(二) --- TCP/IP网络结构(应用层)
  • C++菱形虚拟继承:解开钻石继承的魔咒