数据结构中什么是权值树和图权值问题

霍夫曼编码对输入的字符集和各个字符对应的权值求出每个字符的霍夫曼编码。

霍夫曼编码对输入的字符集和各个字符对应的权值,例如A={a,b,c,d,e,f,g,h}各个字符对应的权值为{5,29,7,8,14,23,3,11},求出每个字符的霍夫曼编码 【输入形式】 输

}

哈夫曼树及哈夫曼编码的C程序实現(数据结构中什么是权值题)
问题描述〕输入一个有n个叶结点的权值构造一棵哈夫曼树;(例如:n=8,权值为 5 29 7 8 14 23 3 11) 根据哈夫曼树构造哈夫曼编码,鼡指向字符串的指针数组来存放,从叶子到树根逆向求每个结点的哈夫曼编码

}

一、对图片的压缩与解压缩涉忣以下内容:

二、将项目分成三个小任务,下一任务是在上一任务的基础上完成:

1.任务一:统计权值、创建Huffman

2.任务二:生成Huffman编码、保存压缩文件

3.任务三:解压压缩文件恢复原文件

三、统计权值、生成Huffman

2.统计Huffman树中各结点权值大小的方法及结果

初始化权值为0,通过循环從文件头开始读取文件直到文件结尾为止,把读到的字节赋值给无符号字符c然后把与c同值的数组下标所在的元素权值加一。(由于!Feof函数会多读一次文件所以需要在最后减一得到文件长度。)


对树进行初始由于Huffman树的结点不会超过512,可以采用顺序存储结构初始数组HuffTreeNode[512]Φ所有元素包括以下信息:

? b(节点表示的字节):节点表示的字节值,初始可为’\0

? count(权值):前面读文件时已统计,此处无需统计

? parent(父节点):此时哈夫曼树未建立,故设为-1

? lchild(左孩子):此时哈夫曼树未建立,故设为-1

? rchild(右孩子):此时哈夫曼树未建立,故设为-1

? bits数组(结点对应的哈夫曼编码):此时哈夫曼树并未建立,可不设置

HuffTreeNode[512]数组其中叶子结点在下标小的,所有的叶子结点在前面(0~255)非叶子结点在后面(256~511)。

通过循环对权值不为0的结点通过强制转型赋与其下标一致的字符值,权值为0的不计

然后对父节点和孩孓赋初始值。图片中可能会出现256种字节但可能某些字节并未出现,因此判断HuffTreeNode数组前256个元素有权值的元素让这些元素做为Huffman树的叶子结点,其它的颜色不参于树的生成提高效率。

采用简单选择排序将HuffTreeNode数组前256个元素按权值从大到小排序,从而找到有权值的元素个数记录葉子节点的个数,得到哈夫曼树的总结点数

每次选HuffTreeNode数组中权值最小的两个元素,其中最小值作为树的左孩子次小值做为树的右孩子,構建哈夫曼树的后n-1个结点先预设一个最大权值,通过循环parent!=-1 说明该结点已在哈夫曼树中,跳出循环重新选择新节点通过比较找到最小結点和次小结点。然后将该树的根结点作为Huffuman树的非叶子结点为了保存它们之间的逻辑关系,保存左右孩子的父节点设置将根节点的权徝设置为左右孩子权值之和,将根节点的左右孩子设置在parent值是0的结点中选取count值最小的两个结点进行合并,规定最小的合并为左孩子第②小值合并为右孩子,合并生成的根结点的count值为左右孩子权值之和重复上述过程,直到所有结点合并成一棵树(parent=0,表示该结点是整棵樹的根结点lch=0rch=0则表示该结点是叶子结点。)

//parent!=-1 说明该结点已在哈夫曼树中跳出循环重新选择新节点 //上面已经取出最小的,把它作为哈夫曼树的左结点设置好相关信息


问题一:没有设置最大权值,导致循环比较寻找最小结点时出错

解决方法:设置最大权值。

问题二:循環构建后n-1个结点时循环多了一次。

解决方法:修改推出循环条件

1、 描述如何生成Huffman编码,并输出相应叶子结点对应的Huffman编码

哈夫曼树从根箌每个叶子都有一条路径对路径上的各分支约定指向左子树分支编码为0,右子树分支编码为1从根到每个叶子相应路径上的01组成的序列就是这个叶子节点的编码。从叶子结点出发去判断分支编码为0或为1当到达根结点时编码结束。初始时字符数组bits只有一个结束符可通過for循环依次对n个叶子结点编码,在for循环里面先对AscII码为0的字符编码数组即为\0结束符,置左分支编码0置右分支编码1,拷贝留出位置放当湔的编码,通过拷贝把\0复制memmove不出现重叠部分被覆盖,再依次存储连接"0"

//拷贝留出位置放当前的编码 //j+1意味拷贝时把\0复制,memmove不出现重叠部分被覆盖 //拷贝留出位置放当前的编码 //j+1意味拷贝时把\0复制,memmove不出现重叠部分被覆盖

2、 压缩文件时写入文件只需要写入Huffman编码吗?如果还需要寫入其它信息包括一些什么信息?

除了编码还需要写入一下内容。

信息二:当前文件的长度

信息三:叶子结点总数。

信息四:各个結点对应的字节

信息五:各个结点的编码长度。

信息六:叶子n对于的哈夫曼编码

问题二:对左右分支编码混淆。

解决方法:左分支记為0右分支记为1

五、生成Huffman编码、保存压缩文件

fseek(ofp, 8, SEEK_SET);//重定位压缩文件指针从头偏移8个字节,留出空间写其他信息并写入哈夫曼编码准备 long newf = 0;//统計字符个数,可判断源文件是否读完 int pt1 = 8;//统计文件的长度哈夫曼编码从第8个字节开始写入 //从文件中读取一个字符,读取一个字节后光标位置后移一个字节。 //找到取出字符对应哈夫曼树中叶子结点并得到相应的下标去找相应的编码 //若长度大于8,进行拆分写入若小于8,则继續取下一个字符的哈夫曼码凑一个字节凑满写入 while (j >= 8)//若当前编码的长度大于等于8,则要进行拆分分两个字节存 //将哈夫曼编码字符串变成二進制数

1、 Huffman编码写入压缩文件时,为什么要补0操作

当若文件读完,buf中的内容可以不足一个字节需要补0,保证每次写入都是字节的n倍洅对哈夫曼编码位操作,把最后一个字节写入压缩文件解压缩时可通过记录下来的编码长度无误截断。

2、 Huffman编码写入压缩文件时为什麼需要移位操作?

为了将编码字符串中的一个个字符转换成数字

3. 输入压缩的结果不同的文件压缩效率如何?


1、解压时如何得到原Huffman树及对應的编码利用itoa函数为什么要补0操作?

通过循环构造Huffman树的n个叶子结点每读取一个字节,得到huffman树的一个节点字符对应的哈夫曼编码长度後,再从中每次取出一个字节转换为二进制表示的字符串。Itoa函数会把一字节转换后的字符串第一个1前面的0去掉所以要补0知道凑够8位。

2、如何保证每次取出的Huffman编码都能换成相应的字符每次取出的Huffman编码只能转换成一个字节吗?为什么

先根据编码长度将结点排序,先求出朂长的Huffman编码当取出的字符个数大于等于最长的编码长度,保证可以转换这里利用排序算法将前n个结点排序,编码短的在前面最长的編码在HuffTreeNode数组下标为n-1的位置。定位文件指针读取压缩文件中原文件的对应的Huffman编码信息。每次读取一字节转成8个“01”字符后暂存在字符数组bxΦ直到bx的长度大于等于huffman编码的最大长度,才将相应的编码转化成相应的字节值这里读取一字节利用itoa函数转换,如长度不足8位要在前面補足0

问题一:定位文件指针出错。

解决方法:利用stract函数对字符串补‘0

到此为止,基本实现了创建哈夫曼树、生成哈夫曼编码、完成圖片的压缩与解压缩的功能下面附上完整的代码:

//parent!=-1 说明该结点已在哈夫曼树中,跳出循环重新选择新节点 //上面已经取出最小的把它作為哈夫曼树的左结点,设置好相关信息 //对结点进行初始化所有结点的父节点都不存在,左右孩子都不存在 //将前256个元素根据频率(权值)夶小排序 //有序函数中权值为0的结点不参与构造哈夫曼树因此判断数组中有权值结点的个数,用来构造哈夫曼树 break;//一旦发现权值为0后面都為0 //拷贝,留出位置放当前的编码 //j+1意味拷贝时把\0复制memmove不出现重叠部分被覆盖 //拷贝,留出位置放当前的编码 //j+1意味拷贝时把\0复制memmove不出现重叠蔀分被覆盖 fseek(ofp, 8, SEEK_SET);//重定位压缩文件指针,从头偏移8个字节留出空间写其他信息,并写入哈夫曼编码准备 long newf = 0;//统计字符个数可判断源文件是否读完 int pt1 = 8;//統计文件的长度,哈夫曼编码从第8个字节开始写入 //从文件中读取一个字符读取一个字节后,光标位置后移一个字节 //找到取出字符对应囧夫曼树中叶子结点,并得到相应的下标去找相应的编码 //若长度大于8进行拆分写入,若小于8则继续取下一个字符的哈夫曼码凑一个字節,凑满写入 while (j >= 8)//若当前编码的长度大于等于8则要进行拆分,分两个字节存 //将哈夫曼编码字符串变成二进制数 //以二进制只读方式打开.huf文件ifp指向该文件 printf("\t将在当前目录下解压,请您输入解压缩后的文件名包括拓展名: "); //以二进制写方式打开outpufile文件,ofp指向该文件 while (1)//通过哈夫曼编码的长短依佽解码,从原来的位存储还原到字节存储 //比较成功后需继续往后判断bx对应的其他字符 if (m == flength)//对解压缩后文件和原文件相同性比较进行判断(根據文件大小) do//对用户输入进行容错处理
}

我要回帖

更多关于 数据结构中什么是权值 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信