b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

[转载]霍夫曼树的详细说明,实现代码和霍夫曼编码示例

电脑杂谈  发布时间:2020-05-16 22:27:01  来源:网络整理

哈夫曼树节点_区块链节点 中继节点_swing 树 组合节点

二叉树-霍夫曼树(最佳二叉树)中有一种特殊的树,它通过一些规则(权重)构造霍夫曼二叉树. 在这个二叉树中,只有叶子节点是有效数据节点(非常重要),引入了其他非叶子节点来构造霍夫曼!

霍夫曼编码是由霍夫曼树执行的一种编码. 通常,它由字符“ 0”和“ 1”表示. 编码的实现过程非常简单,只要实现了霍夫曼树,就规定将遍历左子树的节点编码为“ 0”,遍历右子树的节点编码为“ 1”,结束条件遍历到叶节点!因为如上所述: 霍夫曼树的叶子节点是有效的数据节点!

下图是霍夫曼编码示例的程序效果图:

[转载]哈夫曼树详解、实现代码及哈夫曼编码实例

这是逐步实现此过程的步骤:

如前所述,关键是构造霍夫曼树. 只要构造霍夫曼树,编码就非常简单,但是霍夫曼树的构造是基于实际情况,而不是随便构造的!由于它是二叉树,因此我们首先定义一个二叉树结构:

structtree

{

字符日期; //数据

布尔分钟; //叶子节点

int quanzhi; //重量

结构树*左,*您; //左右两个孩子

} * tre;

权重是我们需要关注的最重要的事情,因为我们想通过权重来构造权重,但是权重如何指定?当然要根据实际情况!叶子节点将其标记为叶子节点,方便以后编码!

为简单起见,第一个示例直接定义了多个霍夫曼树节点,然后通过这些节点构造最终的霍夫曼树!

treetr [9] = {{'a',true,5},{'b',true,2},{'c',true,9},{'d',true,3},{ 'e',true,6}};

tr是一个霍夫曼数组,其中每个元素都是霍夫曼树,我们的任务是“集成”这些元素并将它们连接起来以形成霍夫曼树. 最初,数组的每个元素都是未连接的,我们的任务是通过struct tree * zuo,* you;连接它们. //左右两个孩子,图像将形成二叉树.

我们首先通过语言叙述来构造霍夫曼二叉树:

体重5

b重量2

c体重9

d体重3

e体重6

首先,使用权重值最小的两个节点“集成”一个新节点. 节点的权重是两个最小节点的权重之和. 如下图所示:

[转载]哈夫曼树详解、实现代码及哈夫曼编码实例

然后,将这个新节点的权重与其余元素进行比较,仍然采用两个最小权重的节点来构造一个新节点,并重复此过程直到所有元素都被提取为止,在本例中为霍夫曼树,如下所示:

[转载]哈夫曼树详解、实现代码及哈夫曼编码实例

叶节点(即2、3、5、6、9)是有效的数据节点!节点在构建过程中的左右顺序不影响Ha

Manman树的构造,但是会导致不同的编码,当然,只要不显示前缀代码,编码都是正确的.

实现算法:

算法种类繁多,关键是要了解其构造原理.

通过上面的示例,我们知道要构建霍夫曼树,所需的节点数为有效数据节点的2 * n-1,其中

n是有效数据的数量,如上例所示,有5个有效数据,但最终构造的霍夫曼树具有2 * 5-1 = 9

节点,因此可以基于该属性编写算法:

treetr [9] = {{'a',true,5},{'b',true,2},{'c',true,9},{'d',true,3},{ 'e',true,6}};

5个数据,所以需要9个空格,9-5 = 4个空格用于那些无效节点(霍夫曼树种不是叶子

子节点).

首先,我们遍历此数组以找到最小的两个元素.

然后,将它们移到最前面,并对权重求和以构造一个新节点. 新节点的左和右子树指向最小的两个元素,并且此新节点将插入有效数据之后.

最后,从第2 + 1个元素开始遍历(前两个不需要遍历).

重复上述过程,直到数组被填充,并且填充后的最后一个元素是最后的霍夫曼树.

例如,在第一次遍历之后,数组tr [9]的状态变为:

treetr [9] = {{'d',true,3},{'b',true,2},{'c',true,9},{'a',true,5},{ 'e',true,6},{'',false,5,tr [0],tr [1]}}

最小的两个元素移到最前面,有效数据增加一,新节点的左右子树指向前两个元素.

完整的霍夫曼实现代码如下;

// hfm.cpp: 定义控制台应用程序的入口点.

//

#include“ stdafx.h”

#include

////////////贵州民族大学/////////////////

////////////编译环境vs2010 ///////////////

静态inthfmb = 0;

structtree

{

字符日期; //数据

布尔分钟; //叶子节点

int quanzhi; //重量

结构树*左,*您; //左右两个孩子

} * tre;

structshfm

{

字符日期; //字符数据

char bianm [11]; //霍夫曼编码,最大编码为11(可以根据实际情况修改!)

} hfm [100]; //与霍夫曼编码相对应的真实数据表

voidgettree(tree tr [],int shij哈夫曼树节点,int youx)//构造霍夫曼树,tr树集合,shij集合的实际数据编号,youx集合的有效数据编号

{

//模拟动态增长数组,每次构造新树后插入新数据

如果(2 * youx-1!= shij)

{

printf(“参数不匹配!”);

返回;

区块链节点 中继节点_哈夫曼树节点_swing 树 组合节点

}

int c = 0;

while(youx!= shij)// //有效数字==实际数字时,构造完成!

{

for(int i = c; i

{

//每个周期取两个最小值并将这两个最小值放在当前周期的前两位

if(tr [i] .quanzhi

{

树p = tr [i];

tr [i] = tr [c];

tr [c] = p;

}

if(tr [i] .quanzhi

{

树p = tr [i];

tr [i] = tr [c + 1];

tr [c +1] = p;

}

}

//以下是由最小值构造的新树

tr [youx] .quanzhi = tr [c] .quanzhi + tr [c + 1] .quanzhi;

tr [youx] .you =&tr [c]; //新树的右子节点指向当前循环的最小值之一

tr [youx] .zuo =&tr [c +1]; //新树的左子节点指向当前循环的最小值之一

youx ++; //将新树插入到当前有效数据号之后,并使有效数据号+1

c = c + 2;

}

}

voidbianltree(tree * tr,char ch [])//霍夫曼编码

{

//通过遍历树,获取每个节点的代码

static int i = 0;

if(!tr-> min)//叶子节点

{

ch [i] ='0';

i ++;

bianltree(tr-> zuo,ch); //左侧节点编码为“ 0”

ch [i] ='1';

i ++;

bianltree(tr-> you,ch); //右节点编码为“ 1”

}

如果(tr->分钟)

{

ch [i] =''; //结束标记()

printf(“%c%sn”,tr->日期,ch);

hfm [hfmb] .date = tr->日期;

int j = 0;

同时(j!= i || i> 10)

{

hfm [hfmb] .bianm [j] = ch [j];

j ++;

} //保存编码映射表

hfmb ++;

}

i-; //递归进入右叶子节点时,取消当前分配(当前必须是左叶子节点)

}

int_tmain(int argc,_TCHAR * argv [])

{

treetr [9] = {{'a',true,5},{'b',true,2},{'c',true,9},{'d',true,3},{ 'e',true,6}};

// printf(“%dn”,sizeof(tr)/ sizeof(tree));

gettree(tr,9,5);

char ch [100];

// printf(“%sn”,ch);

bianltree(&tr [8],ch);

返回0;

}

效果:

[转载]哈夫曼树详解、实现代码及哈夫曼编码实例

gettree()函数是构造霍夫曼树的过程,bianltree()是编码霍夫曼树struct shfm的过程

结构是一个映射表,用于存储字符数据及其霍夫曼编码. 是否可以使用. 在这里使用它的原因是它可以通过一次遍历获得所有元素的编码. 就是这样,争取时间空间.

以下是霍夫曼的一些应用示例:

区块链节点 中继节点_swing 树 组合节点_哈夫曼树节点

通过以上介绍,下面将介绍霍夫曼的实际应用.

此示例的模拟效果是: 通过传入字符串字符串,将返回字符串的编码. 并通过传递有效的编码来获取字符串!

完整的代码如下. 在上面的代码的基础上修改了代码,并对上面的代码进行了优化.

// hfm.cpp: 定义控制台应用程序的入口点.

//

#include“ stdafx.h”

#include

////////////贵州民族大学/////////////////

////////////编译环境vs2010 ///////////////

静态inthfmb = 0;

structtree

{

字符日期; //数据

布尔分钟; //叶子节点

int quanzhi; //重量

结构树*左,*您; //左右两个孩子

} * tre;

structshfm

{

字符日期; //字符数据

int len; //代码长度

char bianm [11]; //霍夫曼编码,最大编码为11(可以根据实际情况修改!)

} hfm [100]; //与霍夫曼编码相对应的真实数据表

voidgettree(tree tr [],int shij,int youx)//构造霍夫曼树,tr树集合,shij集合的实际数据编号,youx集合的有效数据编号

{

//模拟动态增长数组,每次构造新树后插入新数据

如果(2 * youx-1!= shij)

{

printf(“参数不匹配!”);

返回;

}

int c = 0;

while(youx!= shij)// //有效数字==实际数字时,构造完成!

{

for(int i = c; i

{

//每个周期取两个最小值并将这两个最小值放在当前周期的前两位

if(tr [i] .quanzhi

{

树p = tr [i];

tr [i] = tr [c];

tr [c] = p;

}

if(tr [i] .quanzhi

{

树p = tr [i];

tr [i] = tr [c + 1];

tr [c +1] = p;

}

}

//以下是由最小值构造的新树

tr [youx] .quanzhi = tr [c] .quanzhi + tr [c + 1] .quanzhi;

tr [youx] .you =&tr [c]; //新树的右子节点指向当前循环的最小值之一

tr [youx] .zuo =&tr [c +1]; //新树的左子节点指向当前循环的最小值之一

youx ++; //将新树插入到当前有效数据号之后,并使有效数据号+1

c = c + 2;

}

返回;

}

voidbianltree(tree * tr)//霍夫曼编码

{

//通过遍历树,获取每个节点的代码

静态字符[100];

static int i = 0;

if(!tr-> min)//叶子节点

{

ch [i] ='0';

i ++;

bianltree(tr-> zuo); //左侧节点编码为“ 0”

ch [i] ='1';

i ++;

区块链节点 中继节点_哈夫曼树节点_swing 树 组合节点

bianltree(tr->您); //右节点编码为“ 1”

}

如果(tr->分钟)

{

ch [i] =''; //结束标记()

printf(“%c%sn”,tr->日期,ch);

hfm [hfmb] .date = tr->日期;

hfm [hfmb] .len = i;

int j = 0;

同时(j!= i || i> 10)

{

hfm [hfmb] .bianm [j] = ch [j];

j ++;

} //保存编码映射表

hfmb ++;

}

i-; //递归进入右节点时,取消当前分配(当前必须是左叶节点)

}

voidchushihuahmf(树* hfmtree,char * str,int i)


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-212392-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 吴淑姬
      吴淑姬

      就算我买的起门票也去不了啊

    • 吕慧妮
      吕慧妮

      我男神太好了

    每日福利
    热点图片
    拼命载入中...