数据结构哈夫曼树的代码

合集下载

最优二叉树(哈夫曼树)的构建及编码

最优二叉树(哈夫曼树)的构建及编码

最优⼆叉树(哈夫曼树)的构建及编码参考:数据结构教程(第五版)李春葆主编⼀,概述1,概念 结点的带权路径长度: 从根节点到该结点之间的路径长度与该结点上权的乘积。

树的带权路径长度: 树中所有叶结点的带权路径长度之和。

2,哈夫曼树(Huffman Tree) 给定 n 个权值作为 n 个叶⼦结点,构造⼀棵⼆叉树,若该树的带权路径长度达到最⼩,则称这样的⼆叉树为最优⼆叉树,也称为哈夫曼树。

哈夫曼树是带权路径长度最短的树,权值较⼤的结点离根较近。

⼆,哈夫曼树的构建1,思考 要实现哈夫曼树⾸先有个问题摆在眼前,那就是哈夫曼树⽤什么数据结构表⽰? ⾸先,我们想到的肯定数组了,因为数组是最简单和⽅便的。

⽤数组表⽰⼆叉树有两种⽅法: 第⼀种适⽤于所有的树。

即利⽤树的每个结点最多只有⼀个⽗节点这种特性,⽤ p[ i ] 表⽰ i 结点的根节点,进⽽表⽰树的⽅法。

但这种⽅法是有缺陷的,权重的值需要另设⼀个数组表⽰;每次找⼦节点都要遍历⼀遍数组,⼗分浪费时间。

第⼆种只适⽤于⼆叉树。

即利⽤⼆叉树每个结点最多只有两个⼦节点的特点。

从下标 0 开始表⽰根节点,编号为 i 结点即为 2 * i + 1 和 2 * i + 2,⽗节点为 ( i - 1) / 2,没有⽤到的空间⽤ -1 表⽰。

但这种⽅法也有问题,即哈夫曼树是从叶结点⾃下往上构建的,⼀开始树叶的位置会因为⽆法确定⾃⾝的深度⽽⽆法确定,从⽽⽆法构造。

既然如此,只能⽤⽐较⿇烦的结构体数组表⽰⼆叉树了。

typedef struct HTNode // 哈夫曼树结点{double w; // 权重int p, lc, rc;}htn;2,算法思想 感觉⽐较偏向于贪⼼,权重最⼩的叶⼦节点要离根节点越远,⼜因为我们是从叶⼦结点开始构造最优树的,所以肯定是从最远的结点开始构造,即权重最⼩的结点开始构造。

所以先选择权重最⼩的两个结点,构造⼀棵⼩⼆叉树。

然后那两个最⼩权值的结点因为已经构造完了,不会在⽤了,就不去考虑它了,将新⽣成的根节点作为新的叶⼦节加⼊剩下的叶⼦节点,⼜因为该根节点要能代表整个以它为根节点的⼆叉树的权重,所以其权值要为其所有⼦节点的权重之和。

数据结构 课程设计之哈夫曼编码

数据结构  课程设计之哈夫曼编码

(一) 哈夫曼树的设计思想对于一组具有确定权值的叶子结点可以构造出多个具有不同带权路径长度的二叉树,其中具有最小带权路径长度的二叉树称作哈夫曼树或者最优二叉树。

首先给定n 个权值创造n 个只含根结点的二叉树,得到一个二叉树林;再在这二叉树林里面找根结点的权值最小和次小的两棵树作成新的二叉树,其中新的二叉树的根结点的权值为摆布子根结点权值之和;最后在二叉树林中把组合过的二叉树删除,再重复第二步,直到最后就剩一颗二叉树的时候得到的这棵二叉树就是哈夫曼树。

(二)哈夫曼编码与解码的设计思想在数据通讯中,时常要将传送的文字转换为二进制字符0 和1 组成的二进制串,称这个过程为编码。

与子相对的是解码或者是译码,就是用与编码相同的方式将二进制串转换称编码前的文字的过程称作解码。

在这里是通过哈夫曼树实现编码与解码的,所以称作是哈夫曼编码与解码。

首先输入一个字符串,还有相应的在哈夫曼树里的权值,这样用哈夫曼树把字符串用二进制串代替它,这个过程要注意树和编码问题,其中树的问题在上面已经解决,主要看编码的问题,就是根据我们输入的字符串和权值建立相应的树模型,这一步完成那编码就已经完成为了,最后打印就行了;然后就是解码,完成编码相应的解码就相对简单了,就是先找到在编码的时候建的那个模型树,将编码中的二进制串再根据权值转换为相应的字符串,这样一步步解码就行了。

以上就是通过用哈夫曼树进行哈夫曼编码与解码如何实现的主要设计思想。

(一)哈夫曼树的流程图不 是图 1 哈夫曼树的流程图(二)编码与解码的流程图图 2 编码与解码的流程图图片说明: (左边)编码流程图, (右边)解码流程图。

开始输入字符串判断权值 建立路径有最小和次小 循环建立二叉树根据树对路径分左 0右 1写出对应结点的编码结束开始初始化哈夫曼链表二叉树林找最小和次小 的二叉树组合成新的二叉树 删除用过的二叉树是不是最后一 个二叉树是结束开始找到树的根结点 输入二进制串扫描根据树的路径打印对应字符继续扫描 是否结束是输出字符串结束否下面给出的是用中缀转后缀算法实现的程序的源代码:#include "stdio.h"#include "string.h"#define MAX 100struct HaffNode{int weight;int parent;char ch;int lchild;int rchild;}*myHaffTree;struct Coding{char bit[MAX];char ch;int weight;}*myHaffCode;void Haffman(int n){int i,j,x1,x2,s1,s2;for (i=n+1;i<=2*n-1;i++) {s1=s2=10000;x1=x2=0;for (j=1;j<=i-1;j++)/*定义常量*//*权值*//*双亲结点下标*//*构造哈夫曼树*//*定义数组*//*字符的权值*//*定义结构体*//*定义哈夫曼函数*//*树的初始化*//*构造哈夫曼树的非叶子结点*/{if(myHaffTree[j].parent==0&&myHaffTree[j].weight<s1){s2=s1;x2=x1;s1=myHaffTree[j].weight;x1=j;/*分配摆布结点*/}else if(myHaffTree[j].parent==0&&myHaffTree[j].weight<s2){s2=myHaffTree[j].weight;x2=j;}}myHaffTree[x1].parent=i;myHaffTree[x2].parent=i;myHaffTree[i].weight=s1+s2;myHaffTree[i].lchild=x1;myHaffTree[i].rchild=x2;/*摆布子组合为新树*/}}void HaffmanCode(int n){int start,c,f,i,j,k;char *cd;/*构造n 个结点哈夫曼编码*/cd=(char *)malloc(n*sizeof(char));myHaffCode=(struct Coding *)malloc((n+1)*sizeof(struct Coding));cd[n-1]='\0';for(i=1;i<=n;++i) /*n 个叶子结点的哈夫曼编码*/ {start=n-1;for(c=i,f=myHaffTree[i].parent;f!=0;c=f,f=myHaffTree[f].parent)if(myHaffTree[f].lchild==c) cd[--start]='0';else cd[--start]='1';for(j=start,k=0;j<n;j++){myHaffCode[i].bit[k]=cd[j];k++;}myHaffCode[i].ch=myHaffTree[i].ch; myHaffCode[i].weight=myHaffTree[i].weight; }free(cd);}Init(){int i,n,m;printf("please input the number of words:"); scanf("%d",&n); /*取编码对应的权值*//*定义有返回值的函数*/m=2*n-1;myHaffTree=(struct HaffNode *)malloc(sizeof(struct HaffNode)*(m+1)); for(i=1;i<=n;i++){printf("please input the word and the equal:");scanf("%s%d",&myHaffTree[i].ch,&myHaffTree[i].weight); myHaffTree[i].parent=0;myHaffTree[i].lchild=0;myHaffTree[i].rchild=0;}for(i=n+1;i<=m;i++){myHaffTree[i].ch ='#';myHaffTree[i].lchild=0;myHaffTree[i].parent=0;myHaffTree[i].rchild=0;myHaffTree[i].weight=0;}Haffman(n);HaffmanCode(n);for(i=1;i<=n;i++){printf("%c %d",myHaffCode[i].ch,myHaffCode[i].weight); printf("\n");}printf("init success!\n");return n;}void Caozuo_C(int m){int n,i,j;char string[50],*p;printf("please input the words :"); scanf("%s",string);n=strlen(string);for(i=1,p=string;i<=n;i++,p++){for(j=1;j<=m;j++)if(myHaffCode[j].ch==*p)printf("%s\n",myHaffCode[j].bit); }}void Caozuo_D(int n){int i,c;char code[1000],*p;printf("please input the coding:"); scanf("%s",code);for(p=code,c=2*n-1;*p!='\0';p++) {if(*p=='0'){c=myHaffTree[c].lchild;if(myHaffTree[c].lchild==0){printf("%c",myHaffTree[c].ch);c=2*n-1;continue;/* 编码函数*//*计算字符串长度*/ /*进行编码*//*解码函数*//*输入二进制编码*//*进行解码*//*结束条件*//*赋值*//* 扫描*//*结束*/}}else if(*p=='1'){c=myHaffTree[c].rchild;if(myHaffTree[c].lchild==0){printf("%c",myHaffTree[c].ch);c=2*n-1; /*赋值*/continue;}}}printf("\n");}void main(){int n;char char1;n=Init();printf("A.coding B.codeprintingwhile(1){scanf("%c",&char1);if(char1=='c')break;switch(char1){case'A':Caozuo_C(n);break;case'B':Caozuo_D(n);break;case'C':;break;}}}/*主函数*//*定义字符*//*函数的调用*/C.exit\nplease input the process:\n");/*判断字符*//*执行编码操作*//*执行解码操作*/哈夫曼编码与解码的实现(一)中缀转后缀算法的运行结果:这部份我主要遇到了如下三个问题,其内容与解决方法如下所列:问题1:刚开始不知道如何建一个好树,因为我开始试着建了几个二叉树,不知道什么原因运行的时候那编码总是不对,跟在草稿纸上自己画的那个二叉树总是不相符,就找原因。

数据结构 哈夫曼编码实验报告

数据结构 哈夫曼编码实验报告

数据结构哈夫曼编码实验报告数据结构哈夫曼编码实验报告1. 实验目的本实验旨在通过实践理解哈夫曼编码的原理和实现方法,加深对数据结构中树的理解,并掌握使用Python编写哈夫曼编码的能力。

2. 实验原理哈夫曼编码是一种用于无损数据压缩的算法,通过根据字符出现的频率构建一棵哈夫曼树,并根据哈夫曼树对应的编码。

根据哈夫曼树的特性,频率较低的字符具有较长的编码,而频率较高的字符具有较短的编码,从而实现了对数据的有效压缩。

实现哈夫曼编码的主要步骤如下:1. 统计输入文本中每个字符的频率。

2. 根据字符频率构建哈夫曼树,其中树的叶子节点代表字符,内部节点代表字符频率的累加。

3. 遍历哈夫曼树,根据左右子树的关系对应的哈夫曼编码。

4. 使用的哈夫曼编码对输入文本进行编码。

5. 将编码后的二进制数据保存到文件,同时保存用于解码的哈夫曼树结构。

6. 对编码后的文件进行解码,还原原始文本。

3. 实验过程3.1 统计字符频率首先,我们需要统计输入文本中每个字符出现的频率。

可以使用Python中的字典数据结构来记录字符频率。

遍历输入文本的每个字符,将字符添加到字典中,并递增相应字符频率的计数。

```pythondef count_frequency(text):frequency = {}for char in text:if char in frequency:frequency[char] += 1else:frequency[char] = 1return frequency```3.2 构建哈夫曼树根据字符频率构建哈夫曼树是哈夫曼编码的核心步骤。

我们可以使用最小堆(优先队列)来高效地构建哈夫曼树。

首先,将每个字符频率作为节点存储到最小堆中。

然后,从最小堆中取出频率最小的两个节点,将它们作为子树构建成一个新的节点,新节点的频率等于两个子节点频率的和。

将新节点重新插入最小堆,并重复该过程,直到最小堆中只剩下一个节点,即哈夫曼树的根节点。

北邮数据结构实验三题目2哈夫曼树(代码)

北邮数据结构实验三题目2哈夫曼树(代码)
int Getm(){return m;}
~Huffman(){delete []HTree;delete []HcodeTable;}//析构函数
};
//初始化哈夫曼树
void Huffman::Init(char *s)
{
int n=0;
while (*(s+n)!='\0')
k=0;//控制哈夫曼数组下标
ctemp=temp[0];//做标记
for (int i=0;i<n;i++)
{
if(temp[i]==ctemp)
{
l++;//统计不同字符出现的频度
if (i==n-1)
HTree[k].weight=l;
}
{
for (int j=0;HcodeTable[i].code[j]!='\0';j++)
{
*d+=HcodeTable[i].code[j];
sum+=1;
}
s++;
n++;
break;
}
}
}
}
void main()
{
cout<<"请选择输入字符串:"<<endl;
char str[1000]={'\0'};
char *s=&str[0];
char c;
int i=0;
bool flag=0;//判断不同字符个数是否>=2
while (cin.get(c))//接收输入字符串,自动除去空格

(完整word版)数据结构课程设计(哈夫曼编码)

(完整word版)数据结构课程设计(哈夫曼编码)

目录目录 (1)1 课程设计的目的和意义 (3)2 需求分析 (5)3 系统设计 (6)(1)设计思路及方案 (6)(2)模块的设计及介绍 (6)(3)主要模块程序流程图 (9)4 系统实现 (14)(1)主调函数 (14)(2)建立HuffmanTree (14)(3)生成Huffman编码并写入文件 (18)(4)电文译码 (19)5 系统调试 (22)小结 (25)参考文献 (26)附录源程序 (27)1 课程设计的目的和意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。

哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。

树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0"码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1"的序列作为和各个对应的字符的编码,这就是哈夫曼编码。

通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。

电报通信是传递文字的二进制码形式的字符串。

但在信息传递时,总希望总长度尽可能最短,即采用最短码。

作为软件工程专业的学生,我们应该很好的掌握这门技术。

在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。

在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。

这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。

在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。

更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见.同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。

数据结构课程设计(哈夫曼编码)要点

数据结构课程设计(哈夫曼编码)要点

┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊目录目录 (1)1 课程设计的目的和意义 (2)2 需求分析 (3)3 系统设计 (4)(1)设计思路及方案 (4)(2)模块的设计及介绍 (4)(3)主要模块程序流程图 (6)4 系统实现 (10)(1)主调函数 (10)(2)建立HuffmanTree (10)(3)生成Huffman编码并写入文件 (13)(4)电文译码 (14)5 系统调试 (16)小结 (18)参考文献 (19)附录源程序 (20)┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊1 课程设计的目的和意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。

哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。

树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。

通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。

电报通信是传递文字的二进制码形式的字符串。

但在信息传递时,总希望总长度尽可能最短,即采用最短码。

作为软件工程专业的学生,我们应该很好的掌握这门技术。

在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。

在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。

这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。

数据结构哈夫曼树例题

数据结构哈夫曼树例题

哈夫曼树是一种特殊的树形结构,主要用于数据压缩和编码等领域。

它通过构建最优二叉树,使得树中每个节点的两个子树权值之和最小,从而在编码过程中达到数据压缩的效果。

下面是一个使用Python实现哈夫曼树的例题:```pythonclass Node:def __init__(self, frequency):self.frequency = frequencyself.left = Noneself.right = Nonedef calculate_frequency(file_data):frequency_map = {}for char in file_data:if char not in frequency_map:frequency_map[char] = 0frequency_map[char] += 1return frequency_mapdef huffman_tree(frequency_map):queue = [Node(frequency) for frequency in frequency_map.values()]while len(queue) > 1:node1 = queue.pop(0)node2 = queue.pop(0)merged = Node(node1.frequency + node2.frequency)merged.left = node1merged.right = node2queue.append(merged)return queue[0] # 返回根节点def encode(huffman_tree, file_data):result = ""for char in file_data:node = huffman_tree.find(char) # 查找对应节点result += chr(int(node.weight) + ord(' ')) # 将权值转化为字符,添加到结果中return resultdef decode(huffman_tree):return huffman_tree.left # 直接使用左子树解码,可以得到原数据```解题思路:1. 首先需要统计文件的字符频率,构造一个字符到频率的映射,也就是构建哈夫曼树的节点。

哈夫曼编码

哈夫曼编码

设计哈夫曼编码【问题描述】根据给定字符的使用频率,为其设计哈夫曼编码。

【基本要求】●功能:求出n个字符的哈夫曼编码。

●输入:输入n个字符和字符在电文中的使用频率。

●输出:n个字符的哈夫曼编码。

【测试数据】输入字符集{a,b,c,d,e,f,g,h}的使用频率{5,29,7,8,14,23,3,11}(扩大100倍),预期的输出为这8个字符的哈夫曼编码a:0001;b:10;c:1110;d:1111;e:110;f:01;h:001 。

【数据结构】哈夫曼树中没有度数为1的分支结点,有n个叶子结点的哈夫曼树中共有2n-1个结点,可以用大小为2n-1的数组来存储哈夫曼树中的结点。

在哈夫曼算法中,对每个结点,既需要知道双亲的信息,又需要知道其孩子结点的信息,因此,其存储结构为:#define n 8 /*叶子数目*/#define m 2*n-1 /*结点总数*/typedef struct{int weight; /*结点的权值*/int lchild, rchild, parent; /*左、右孩子及双亲的下标*/}htnode;typedef htnode humffmantree[m+1]; /* humffmantree结构数组类型,其0号单元不用*/ humffmantree ht;其中,每个结点包括4个域,weight域存放结点的权值;lchild、rchild域分别为结点的左右孩子在数组中的下标,叶子结点的这两个域的值为0;parent域是结点的双亲在数组中的下标。

这里设置parent域不仅仅是为了使涉及双亲的运算方便,它的主要作用是根和非根结点。

之所以要区分根与非跟结点,是因为在当前森林中合并两棵二叉树时,必须在森林的所有结点中先取两个权值最小的根结点,因此,有必要为每个结点设置一个标记以区分根和非跟结点为实现方便,将n个叶子结点集中存储在前面的n个位置(下标为1-n),后面n-1个位置存储n-1个非叶子结点。

计算机数据结构知识点梳理 哈夫曼(Huffman)树和哈夫曼编码

计算机数据结构知识点梳理		哈夫曼(Huffman)树和哈夫曼编码
(2)在F中选取根结点的权值最小和次小的两棵二叉树作为左、右子树构造一 棵新的二叉树,这棵新的二叉树根结点的权值为其左、右子树根结点权值之 和;
(3)在集合F中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入 到集合F中;
(4)重复(2)(3)两步,当F中只剩下一棵二叉树时,这棵二叉树便是所要 建立的哈夫曼树。
(3)深度为h的哈夫曼树,其叶子结点的最大编码长度为h-1。
[题1]若度为m的哈夫曼树,其叶子结点个数为n,则非叶子结点 的个数为( )。
A.n-1 B.[n/m]-1 C.[(n-1)/(m-1)] D.[n/(m-1)]-1
分析:在构造度为m的哈夫曼树过程中,每次把m个子结点合并 为一个父结点(第一次合并可能少于m个子结点),每次合并 减少m-1个结点,从n个叶子结点减少到最后只剩一个父结点共 需[(n-1)/(m-1)]次合并,每次合并增加一个非叶子结点。
5、对哈夫曼树编码的总结
(1)哈夫曼编码是能使电文代码总长最短的编码方式。此结论由哈夫曼树是带 权路径长度最小的树的特征可得。
(2)哈夫曼编码是一种前缀编码,保证其在译码时不会产生歧义。因为,在哈 夫曼编码中,每个字符都是叶子结点,而叶子结点不可能从根结点到其他叶 子结点的路径上,所以一个字符的哈夫曼编码不可能是另一个字符的哈夫曼 编码的前缀。
知识点10:哈夫曼(HUFFMAN)树和哈夫曼编码
1、哈夫曼树(又称最优二叉树),是指对于一 组带有确定权值的叶结点,构造的具有最小带
权路径长度的二叉树。
2、哈夫曼树的构造方法的基本思想
(1)由给定的n个权值{W1,W2,…,Wn}构造n棵只有一个叶结点的二叉树, 从而得到一个二叉树的集合F={T1,T2,…,Tn};

哈夫曼树度为m

哈夫曼树度为m

哈夫曼树度为m1. 哈夫曼树的概念哈夫曼树(Huffman Tree)是一种特殊的二叉树,它的每个非叶子节点都有度为m (m>=2)的子节点。

哈夫曼树是一种用来构建哈夫曼编码的数据结构,它能够有效地压缩数据,减少存储空间的占用。

2. 哈夫曼编码的原理哈夫曼编码是一种变长编码方式,将频率较高的字符用较短的编码表示,频率较低的字符用较长的编码表示,从而实现对数据的压缩。

而哈夫曼树是构建哈夫曼编码的关键。

哈夫曼编码的构建过程如下:1.统计字符的频率:对待编码的数据进行扫描,统计每个字符出现的频率。

2.构建哈夫曼树:根据字符的频率构建哈夫曼树。

频率较低的字符位于树的较低层,频率较高的字符位于树的较高层。

3.生成哈夫曼编码:从哈夫曼树的根节点开始,沿着左子树路径走为0,沿着右子树路径走为1,直到叶子节点。

叶子节点的路径即为字符的哈夫曼编码。

3. 构建哈夫曼树度为m的方法构建哈夫曼树度为m的方法与构建普通哈夫曼树的方法类似,只是在构建过程中需要考虑节点的度数。

下面以度为3的哈夫曼树为例进行说明。

1.统计字符的频率:对待编码的数据进行扫描,统计每个字符出现的频率。

2.构建哈夫曼树:首先将所有字符的频率作为权值,构建一个初始的度为3的哈夫曼树。

然后,从频率最小的节点开始,逐渐合并节点,直到只剩下一个根节点。

–合并节点的方法:每次选择权值最小的m个节点,将它们合并为一个新的父节点,并将新节点的权值设置为这m个节点权值之和。

–合并节点的顺序:由于要构建度为3的哈夫曼树,所以每次合并节点时,需要选择m个节点。

可以采用贪心算法,每次选择权值最小的m个节点进行合并。

3.生成哈夫曼编码:从哈夫曼树的根节点开始,沿着左子树路径走为0,沿着右子树路径走为1,直到叶子节点。

叶子节点的路径即为字符的哈夫曼编码。

4. 哈夫曼编码的优缺点优点1.哈夫曼编码是一种无损压缩算法,可以完全还原原始数据。

2.哈夫曼编码能够根据字符的频率进行编码,使得频率较高的字符用较短的编码表示,从而实现对数据的有效压缩。

哈夫曼编码数据结构

哈夫曼编码数据结构

哈夫曼编码是一种编码方式,它使用变长编码来表示给定字符集中字符的序列。

它基于一种叫做哈夫曼树的数据结构,它通过将每个字符与一个编码树上的节点相关联来实现编码。

哈夫曼树由若干个叶节点和中间节点组成,每个叶节点包含一个字符和一个权重值,而中间节点包含两个子节点和一个权重值。

权重值是指字符或子节点的频率。

叶节点的权重值是字符的频率,中间节点的权重值是其子节点的权重值之和。

哈夫曼树的构造需要将每个字符和其对应的权重值放入一个优先队列中,每次从优先队列中取出两个最小权重值的节点,将它们作为孩子节点构成新的节点,并将新节点的权重值设为两个孩子节点权重值之和,然后将新节点重新插入优先队列。

这个过程会一直重复,直到优先队列中只剩下一个节点,这个节点就是哈夫曼树的根节点。

哈夫曼树可以用来实现变长编码,即每个字符都有一个相对较短的编码,而字符出现的频率越高,其编码就越短。

实现变长编码的方法是从根节点开始,向下
遍历哈夫曼树,每向左走一步就记为“0”,每向右走一步就记为“1”,直到遍历到叶节点,这个路径上的“0”和“1”就是叶节点的编码。

数据结构哈夫曼树编码

数据结构哈夫曼树编码

数据结构哈夫曼树编码一、引言二、哈夫曼树的定义1. 节点的概念2. 哈夫曼树的定义三、哈夫曼编码的概念1. 编码方式2. 码长和平均码长四、哈夫曼编码的实现方法1. 构建哈夫曼树a. 构建思路及步骤b. 构建示例图解2. 编码过程a. 编码步骤及示例图解b. 编码实现代码示例3. 解码过程a. 解码步骤及示例图解b. 解码实现代码示例五、哈夫曼编码的优缺点1. 优点2. 缺点六、应用实例七、总结一、引言:随着信息技术的飞速发展,数据处理已经成为当今社会中一个不可或缺的部分。

在数据处理中,如何高效地压缩数据是一个非常重要的问题。

而哈夫曼树编码作为一种高效的压缩算法,在数据传输和存储方面有着广泛应用。

二、哈夫曼树的定义:1. 节点的概念:哈夫曼树是一种二叉树,由根节点、左子树和右子树组成。

每个节点可以有零个或两个子节点。

叶子节点是指没有子节点的节点,而非叶子节点则至少有一个子节点。

2. 哈夫曼树的定义:哈夫曼树是一种特殊的二叉树,它的所有叶子节点都带有权值。

对于任意一个哈夫曼树,将其所有叶子节点按照权值从小到大排列,则可得到一组序列W={w1,w2,...,wn}。

哈夫曼树的构建过程就是将这组序列转化为一棵二叉树。

三、哈夫曼编码的概念:1. 编码方式:哈夫曼编码是一种前缀编码方式,即每个字符的编码都不是其他字符编码的前缀。

2. 码长和平均码长:对于一个字符c,其在哈夫曼编码中所占用的位数称为其码长Lc。

而整个字符串的平均码长Lavg则是所有字符在哈夫曼编码中所占用位数之和除以字符串长度n。

四、哈夫曼编码的实现方法:1. 构建哈夫曼树a. 构建思路及步骤:(1)将所有字符按照权值从小到大排序,构成初始节点集合。

(2)从节点集合中选出两个权值最小的节点作为左右子节点,构建一棵新的二叉树,并将该二叉树的根节点插入到节点集合中。

(3)重复步骤2,直到只剩下一个节点为止。

b. 构建示例图解:2. 编码过程a. 编码步骤及示例图解:(1)遍历哈夫曼树,对于每个叶子节点记录其路径上所有非叶子节点的左右分支信息,用0表示左分支,用1表示右分支。

数据结构——哈夫曼(Huffman)树+哈夫曼编码

数据结构——哈夫曼(Huffman)树+哈夫曼编码

数据结构——哈夫曼(Huffman)树+哈夫曼编码前天acm实验课,⽼师教了⼏种排序,抓的⼀套题上有⼀个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这⾥我就结合课本,整理⼀篇关于哈夫曼树的博客。

哈夫曼树的介绍Huffman Tree,中⽂名是哈夫曼树或霍夫曼树,它是最优⼆叉树。

定义:给定n个权值作为n个叶⼦结点,构造⼀棵⼆叉树,若树的带权路径长度达到最⼩,则这棵树被称为哈夫曼树。

这个定义⾥⾯涉及到了⼏个陌⽣的概念,下⾯就是⼀颗哈夫曼树,我们来看图解答。

(01) 路径和路径长度定义:在⼀棵树中,从⼀个结点往下可以达到的孩⼦或孙⼦结点之间的通路,称为路径。

通路中分⽀的数⽬称为路径长度。

若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。

例⼦:100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。

(02) 结点的权及带权路径长度定义:若将树中结点赋给⼀个有着某种含义的数值,则这个数值称为该结点的权。

结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

例⼦:节点20的路径长度是3,它的带权路径长度= 路径长度 * 权 = 3 * 20 = 60。

(03) 树的带权路径长度定义:树的带权路径长度规定为所有叶⼦结点的带权路径长度之和,记为WPL。

例⼦:⽰例中,树的WPL= 1*100 + 2*50 +3*20 + 3*10 = 100 + 100 + 60 + 30 = 290。

⽐较下⾯两棵树上⾯的两棵树都是以{10, 20, 50, 100}为叶⼦节点的树。

左边的树WPL=2*10 + 2*20 + 2*50 + 2*100 = 360 右边的树WPL=350左边的树WPL > 右边的树的WPL。

你也可以计算除上⾯两种⽰例之外的情况,但实际上右边的树就是{10,20,50,100}对应的哈夫曼树。

⾄此,应该堆哈夫曼树的概念有了⼀定的了解了,下⾯看看如何去构造⼀棵哈夫曼树。

数据结构哈夫曼编码

数据结构哈夫曼编码

数据结构哈夫曼编码
哈夫曼编码是一种用于数据压缩的算法,它基于哈夫曼树(HuffmanTree)进行编码。

哈夫曼编码的基本思想是:对于出现频率高的字符,其编码长度较短;而对于出现频率低的字符,其编码长度较长。

这样,通过调整字符的编码长度,可以有效地压缩数据。

哈夫曼编码的具体步骤如下:
1.统计原始数据中每个字符的出现频率。

2.构建哈夫曼树。

在构建过程中,每次将两个权值最小的节点合并,并将它们的权值相加。

同时,将新生成的节点的权值作为新字符的出现频率。

3.根据哈夫曼树生成哈夫曼编码。

对于哈夫曼树中的每个字符,从根节点到该字符所在节点的路径可以形成一个二进制编码。

通常约定左分支标记为0,右分支标记为1。

这样,从根节点到每个叶节点的路径就可以形成一个二进制编码,该编码即为对应字符的哈夫曼编码。

4.使用哈夫曼编码对原始数据进行压缩。

对于原始数据中的每个字符,根据其哈夫曼编码进行编码,最终得到压缩后的数据。

需要注意的是,哈夫曼编码是一种无损压缩算法,即压缩和解压过程中可以完全还原原始数据。

同时,由于哈夫曼编码是基于字符出现频率进行编码的,因此对于出现频率高的字符,其编码长度较短;而对于出现频率低的字符,其编码长度较长。

这样可以有效地减少数据的存储空间,提高数据压缩率。

PTA数据结构哈夫曼树与哈夫曼编码

PTA数据结构哈夫曼树与哈夫曼编码

PTA数据结构哈夫曼树与哈夫曼编码⽂章⽬录题⽬描述题⽬背景:介绍什么是哈夫曼树和哈夫曼编码, 不影响做题哈夫曼树(Huffman Tree)⼜称最优⼆叉树,是⼀种带权路径长度最短的⼆叉树。

所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。

树的路径长度是从树在数据通信中,需要将传送的⽂字转换成⼆进制的字符串,⽤0,1码的不同排列来表⽰字符。

例如,需传送的报⽂为“AFTER DATA EAR ARE ART AREA”,这⾥⽤到的字符集为“A,E,R,T,F,D”,各字母出现的次数为{8,4,5,3,1,1}。

现要为使不等长编码为前缀编码(即要求⼀个字符的编码不能是另⼀个字符编码的前缀),可⽤字符集中的每个字符作为叶⼦结点⽣成⼀棵编码⼆叉树,为了获得传送报⽂的最短长度,可将每个字符的出现频率作为字符结点的权值赋予该结点上,显然字使⽤本题要求从键盘输⼊若⼲电⽂所⽤符号及其出现的频率,然后构造哈夫曼树,从⽽输出哈夫曼编码。

注意:为了保证得到唯⼀的哈夫曼树,本题规定在构造哈夫曼树时,左孩⼦结点权值不⼤于右孩⼦结点权值。

如权值相等,则先选优先级队列中先出队的节点。

编码时,左分⽀取“0”,右分⽀取“1”。

输⼊格式输⼊有3⾏第1⾏:符号个数n(2~20)第2⾏:⼀个不含空格的字符串。

记录着本题的符号表。

我们约定符号都是单个的⼩写英⽂字母,且从字符‘a’开始顺序出现。

也就是说,如果 n 为 2 ,则符号表为 ab;如果 n 为 6,则符号为 abcdef;以此类推。

第3⾏:各符号出现频率(⽤乘以100后的整数),⽤空格分隔。

输出格式先输出构造的哈夫曼树带权路径长度。

接下来输出n⾏,每⾏是⼀个字符和该字符对应的哈夫曼编码。

字符按字典顺序输出。

字符和哈夫曼编码之间以冒号分隔。

样例输⼊:8abcdefgh5 29 7 8 14 23 3 11输出:271a:0001b:10c:1110d:1111e:110f:01g:0000h:001⼀点说明关于题⽬描述中的"如权值相等,则先选优先级队列中先出队的节点"可以参考上图, 权值为7的节点选择了权值为8的叶⼦节点, ⽽不是权值为8的⼦树感觉题⽬想表达的意思是, 若权值相等,则先选优先级队列中先⼊队的节点(如有错误, 望指正)想法利⽤优先队列维护⼩根堆(因为建树时,要选两个权值最⼩的),利⽤哈夫曼算法建树,再根据所建哈夫曼树,利⽤深搜回溯,得到各个字符的哈夫曼编码和树的带权路径长度实现#include <cstdio>#include <iostream>#include <string>#include <queue>#include <vector>using namespace std;struct node{int weight;char ch = 'z' + 1; // 这样在优先队列⾃定义排序时, 可以做到权值相等,则先选优先级队列中先出队的节点node *lchild, *rchild;};// ⾃定义优先队列的排序⽅式, 权值⼩优先, 权值相等,则先选优先级队列中先出队的节点struct cmp{bool operator() (node* a, node* b){if(a->weight == b->weight)return a->ch > b->ch;return a->weight > b->weight;}};int n, WPL; // n:结点数 WPL:树的带权路径长度(⾮叶⼦节点的权值和)string str;priority_queue<node, vector<node*>, cmp> q; //vector<char> ans[100]; // 存放哈夫曼编码vector<char> code; // ⽤于深搜得到哈夫曼编码node* createTree() // 建⽴哈夫曼树{node* r;while(!q.empty()){if(q.size() == 1){node* a = q.top();q.pop();r = a;break;}else{node* a = q.top();q.pop();node* b = q.top();q.pop();node* c = new node();c->weight = a->weight + b->weight;c->lchild = a;c->rchild = b;r = c;q.push(c);}}return r;}void print() // 输出前缀编码{cout << WPL << endl;for(int i=0; i<n; i++){cout << str[i] << ":";int index = str[i] - 'a';for(int j=0; j<ans[index].size(); j++)cout << ans[index][j];cout << endl;}}void dfs(node* root) // 深搜回溯得到哈夫曼编码和树的带权路径长度{if(root->lchild != NULL || root->rchild != NULL)WPL += root->weight; // WPL即⾮叶⼦节点的权值之和if(root->lchild == NULL && root->rchild == NULL){char ch = root->ch;ans[ch-'a'] = code; // 根据叶⼦节点的字符, 判断是谁的哈夫曼编码return;}if(root->lchild != NULL){code.push_back('0');dfs(root->lchild);code.pop_back(); // 回溯}if(root->rchild != NULL){code.push_back('1');dfs(root->rchild);code.pop_back(); // 回溯}return;}int main(){cin >> n;cin >> str;for(int i=0; i<n; i++) // 读⼊各节点的权值, 利⽤优先队列维护⼩根堆, 便于建树{node* temp = new node(); // 不要忘记给指针分配空间cin >> temp->weight;temp->ch = str[i];temp->lchild = temp->rchild = NULL;q.push(temp);}node* root = createTree(); // 建⽴哈夫曼树dfs(root); // 回溯得到哈夫曼编码及WPLprint();return 0;}。

数据结构哈夫曼编码译码c语言

数据结构哈夫曼编码译码c语言

数据结构哈夫曼编码译码c语言哈夫曼编码是一种经典的数据压缩算法。

这种算法可以根据数据中出现频率最高的字符生成一个种类较少的编码表,然后用这个编码表来对数据进行编码,从而达到压缩数据的效果。

哈夫曼编码的核心是生成编码表,生成编码表的过程包括以下几个步骤:1. 统计字符出现频率。

遍历一遍数据,统计每个字符出现的次数。

2. 创建哈夫曼树。

将每个字符出现的次数作为权值,构造一棵哈夫曼树。

构造哈夫曼树需要用到一种优先队列。

3. 生成编码表。

对哈夫曼树进行遍历,当遇到一个叶子节点时,将它的路径上的所有节点转换成一个编码,这个编码就是该节点代表的字符的哈夫曼编码。

4. 对数据进行编码。

按照编码表,将原始数据中的每个字符都替换成对应的哈夫曼编码,得到压缩数据。

哈夫曼编码的解码操作相对简单,只需要根据编码表将每个哈夫曼编码转换成它代表的字符,再将这些字符拼接起来就可以得到原始数据。

以下是C语言实现哈夫曼编码和译码的例子:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_NODE 100typedef struct node {char data;int freq;int parent, lchild, rchild;} Node;int nodes_num;Node* nodes;void build_huffman_tree() {int i, j, min1, min2;for (i = 0; i < nodes_num - 1; i++) {min1 = min2 = -1;for (j = 0; j < nodes_num + i; j++) {if (nodes[j].parent == -1) {if (min1 == -1 || nodes[j].freq < nodes[min1].freq) {min2 = min1;min1 = j;} else if (min2 == -1 || nodes[j].freq < nodes[min2].freq) { min2 = j;}}}nodes[min1].parent = nodes_num + i;nodes[min2].parent = nodes_num + i;nodes[nodes_num + i].lchild = min1;nodes[nodes_num + i].rchild = min2;nodes[nodes_num + i].freq = nodes[min1].freq + nodes[min2].freq;}}nodes_num = 0;nodes = (Node*)malloc(MAX_NODE * sizeof(Node));for (i = 0; i < MAX_NODE; i++) {nodes[i].freq = nodes[i].parent = -1;nodes[i].lchild = nodes[i].rchild = -1;}build_huffman_tree();codes_num = 0;codes = (Code*)malloc(nodes_num * sizeof(Code));printf("src: %s\n", src);return 0;}```上述代码中,我们使用结构体来表示哈夫曼树的节点,其中包括该节点的权值(即字符出现的次数)、父节点、左右孩子节点等信息。

数据结构实验哈夫曼树及哈夫曼编码c语言

数据结构实验哈夫曼树及哈夫曼编码c语言

数据结构实验报告:哈夫曼树及哈夫曼编码一、实验目的1. 理解哈夫曼树及哈夫曼编码的概念和原理;2. 掌握C语言中哈夫曼树及哈夫曼编码的实现方法;3. 分析和讨论哈夫曼编码在实际应用中的优势和不足。

二、实验内容和步骤1. 哈夫曼树的构建1.1 通过C语言实现哈夫曼树的构建算法;1.2 输入一组权值,按哈夫曼树构建规则生成哈夫曼树;1.3 输出生成的哈夫曼树结构,并进行可视化展示。

2. 哈夫曼编码的实现2.1 设计哈夫曼编码的实现算法;2.2 对指定字符集进行编码,生成哈夫曼编码表;2.3 对给定字符串进行哈夫曼编码,并输出编码结果。

三、实验过程及结果1. 哈夫曼树的构建在C语言中,通过定义结构体和递归算法实现了哈夫曼树的构建。

根据输入的权值,依次选择权值最小的两个节点构建新的父节点,直至构建完成整棵哈夫曼树。

通过调试和可视化展示,确认了程序正确实现了哈夫曼树的构建。

2. 哈夫曼编码的实现经过分析和设计,利用哈夫曼树的特点实现了哈夫曼编码的算法。

根据生成的哈夫曼树,递归地生成字符对应的哈夫曼编码,并输出编码结果。

对指定的字符串进行了编码测试,验证了哈夫曼编码的正确性和有效性。

四、实验结果分析1. 哈夫曼编码在数据传输和存储中具有较高的压缩效率和可靠性,能够有效减少数据传输量和存储空间;2. 哈夫曼树及哈夫曼编码在通信领域、数据压缩和加密等方面有着广泛的应用和重要意义;3. 在实际应用中,哈夫曼编码的构建和解码算法需要较大的时间和空间复杂度,对于大规模数据的处理存在一定的局限性。

五、实验总结通过本次实验,深入理解了哈夫曼树及哈夫曼编码的理论知识,并掌握了C语言中实现哈夫曼树及哈夫曼编码的方法。

对哈夫曼编码在实际应用中的优势和局限性有了更深入的认识,这对今后的学习和工作有着积极的意义。

六、参考文献1. 《数据结构(C语言版)》,严蔚敏赵现军著,清华大学出版社,2012年;2. 《算法导论》,Thomas H. Cormen 等著,机械工业出版社,2006年。

哈夫曼树与哈夫曼树编码实验原理

哈夫曼树与哈夫曼树编码实验原理

哈夫曼树与哈夫曼树编码实验原理哈夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构。

它的主要原理是通过构建一个最优的二叉树来实现编码和解码的过程。

以下是哈夫曼树和哈夫曼编码的实验原理:1. 构建哈夫曼树:- 给定一组需要进行编码的字符及其出现频率。

通常,这个频率信息可以通过统计字符在原始数据中的出现次数来得到。

- 创建一个叶节点集合,每个叶节点包含一个字符及其对应的频率。

- 从叶节点集合中选择两个频率最低的节点作为左右子节点,创建一个新的父节点。

父节点的频率等于左右子节点频率的和。

- 将新创建的父节点插入到叶节点集合中,并将原来的两个子节点从集合中删除。

- 重复上述步骤,直到叶节点集合中只剩下一个节点,即根节点,这个节点就是哈夫曼树的根节点。

2. 构建哈夫曼编码:- 从哈夫曼树的根节点开始,沿着左子树走一步就表示编码的0,沿着右子树走一步表示编码的1。

- 遍历哈夫曼树的每个叶节点,记录从根节点到叶节点的路径,得到每个字符对应的编码。

由于哈夫曼树的构建过程中,频率较高的字符在树中路径较短,频率较低的字符在树中路径较长,因此哈夫曼编码是一种前缀编码,即没有任何一个字符的编码是其他字符编码的前缀。

3. 进行数据压缩:- 将原始数据中的每个字符替换为其对应的哈夫曼编码。

- 将替换后的编码串连接起来,形成压缩后的数据。

4. 进行数据解压缩:- 使用相同的哈夫曼树,从根节点开始,按照压缩数据中的每个0或1进行遍历。

- 当遇到叶节点时,就找到了一个字符,将其输出,并从根节点重新开始遍历。

- 继续按照压缩数据的编码进行遍历,直到所有的编码都解压为字符。

通过构建最优的哈夫曼树和对应的编码表,可以实现高效的数据压缩和解压缩。

频率较高的字符使用较短的编码,从而达到减小数据大小的目的。

而频率较低的字符使用较长的编码,由于其出现频率较低,整体数据大小的增加也相对较小。

c++哈夫曼编码与解码的实现

c++哈夫曼编码与解码的实现

在C++编程中,哈夫曼编码与解码是一个非常重要且有趣的主题。

它涉及到数据压缩和信息传输中的关键技术,对于理解算法和数据结构有着重要的意义。

下面我将详细讨论C++中哈夫曼编码与解码的实现。

1. 哈夫曼编码哈夫曼编码是一种有效的编码方式,用于无损数据压缩。

它通过根据字符出现的频率来构建不等长的编码,将高频字符用短编码表示,低频字符用长编码表示,从而减少数据传输的长度。

在C++中,我们可以通过构建哈夫曼树来实现编码过程。

2. 哈夫曼解码哈夫曼解码是编码的逆过程,它通过哈夫曼树和编码表来将编码还原成原始数据。

在C++中,我们可以使用递归或循环的方式来实现哈夫曼解码算法。

3. 实现思路在C++中实现哈夫曼编码与解码,我们可以首先构建哈夫曼树,然后根据哈夫曼树生成编码表,利用编码表对原始数据进行编码,并提供相应的解码函数进行解压。

在构建哈夫曼树时,可以使用最小堆或优先队列来辅助实现。

4. 代码示例下面是一个简单的C++代码示例,用于实现哈夫曼编码与解码:```cpp// 在这里插入你的代码示例```5. 个人观点我对哈夫曼编码与解码的实现非常感兴趣,它涉及到了树形数据结构、优先队列等知识,并且能够在实际应用中发挥重要作用。

在C++编程中,掌握哈夫曼编码与解码的实现对于提高编程技能和理解数据压缩算法都有着重要的意义。

总结回顾:通过本文的讨论,我们对C++中哈夫曼编码与解码的实现有了更深入的理解。

我们首先了解了哈夫曼编码和解码的基本原理,然后通过代码示例展示了其具体实现方法。

我也共享了自己对这一主题的个人观点和理解。

通过学习和掌握哈夫曼编码与解码的实现,我们可以更好地应用在实际项目中,提高程序的效率和性能。

在这篇文章中,我们全面地讨论了哈夫曼编码与解码的实现方法,并根据指定的主题,让你更深入地理解了这一内容。

希望这篇文章对你有所帮助,也欢迎你在实际项目中尝试应用哈夫曼编码与解码算法,不断提升自己的编程能力。

哈夫曼编码与解码在现代通信和数据存储中起着非常重要的作用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}htnode;
htnode ht[maxval];
typedef struct{
char cd[10];
}huffmancode;
huffmancode hc[maxval];
int n,maxline;
int cnt[27];
char exp[256], str[27];
}
void Decoding()
{ FILE *fp;
char ch;
int k=0,start;
char filename[20];
printf("please input filename:codefile.txt\n");
scanf("%s",filename);
}
min1=32767;
for (j=0;j<i;j++)
if(ht[j].weight<min1 && ht[j].parent==0 && j!=s1)
{
s2=j;min1=ht[j].weight;
{
while((ht[k].lchild!=0)||(ht[k].rchild!=0))
{
ch=fgetc(fp);
if(ch=='0') k=ht[k].lchild;
}
void Print_code()
{
int i;
printf("每种字符的前缀编码:\n");
for(i=0;i<n;i++)
{
printf("%c\t%s\n",ht[i].ch,hc[i].cd);
}
}
int Menu_select()
}
ht[s1].parent=i;ht[s2].parent=i;
ht[i].lchild=s1; ht[i].rchild=s2;
ht[i].weight=ht[s1].weight+ht[s2].weight;
}
else if(ch=='1') k=ht[k].rchild;
}
printf("%c",ht[k].ch);k=2*n-2;
}
}
void Print_hufmantree()
}
void Creat_huffmancode()
{
int c,p,i;
char cd[10];
int start;
for(i=0;i<n;i++)
{
start=n-1;
cd[start]='\0';
}
printf("Got string!\n");
fclose(fp);
}
void Read_txt()
{
FILE *fp;
int i = 0;
char ch;
char filename[20];
printf("please input filename:a.txt\n");
c=i;
p=ht[i].parent;
while(p>0)
{
if(ht[p].lchild==c)
cd[--start]='0';
else
cd[--start]='1';
{
int i,j,m,s1,s2;
m=2*n-1;
for(i=0;i<n;i++)
{
ht[i].ch=str[i];
ht[i].weight=cnt[i];
ht[i].lchild=0;
ht[i].parent=0;
{
int i;
printf("哈夫曼树的终态:\n");
for(i=0;i<2*n-1;i++)
printf("%c\t%d\t%d\t%d\t%d\n",ht[i].ch,ht[i].weight,
ht[i].lchild,ht[i].parent,ht[i].rchild);
{
printf("can't open file!\n");
exit(0);
}
printf("请输入待编码的内容(以'#'键结束输入):\n");
ch=getchar();
while(ch!='#')
{
fputc(ch,fp);
ch=getchar();
k=ch-'a';
temp[k]++;
}
}
for(i=0;i<26;++i)
if(temp[i]!=0 )
{
str[j]=(char)(i+'a');
{
ch=fgetc(fp);
exp[i++]=ch;
}
exp[i]='\0';
maxline = i;
fclose( fp );
}
void Count_char()
{
int i,j=0,k;
char ch;
{
printf("can't open file!\n");
exit(0);
}
printf("文件中的编码内容为:\n");
for(i=0;i<maxline-1;i++)
{
for(j=0;j<n;j++)
}
for(i=n;i<m;i++)
{
int min1=101;
for(j=0;j<i;j++)
if(ht[j].weight<min1 &&ht[j].parent==0)
{
s1=j;min1=ht[j].weight;
FILE *fp;
char p[10];
char filename[20];
printf("please input filename:codefile.txt\n");
scanf("%s",filename);
if((fp=fopen(filename,"w"))==NULL)
c=p;
p=ht[p].parent;
}
strcpy(hc[i].cd,&cd[start]);
}
free(cd);
}
void Encoding()
{
int i,j,k;
{ char c;
int i;
do{
system("cls");
system("graftabl 936");
printf("\t****************************************************************");
if((fp=fopen(filename,"r"))==NULL)
{
printf("can't open file!\n");
exit(0);
}
k=2*n-2;
printf("译码为:\n");
while(ቤተ መጻሕፍቲ ባይዱfeof(fp))
printf("\t | 3. 形成哈夫曼树并打印 |\n");
printf("\t | 4. 求每种字符对应的前缀编码并打印 |\n");
printf("\t | 5. 对电文编码并写入codefile.txt文件中 |\n");
printf("\t\t\t**哈夫曼编码译码器!**\n");
printf("\t | 1. 输入要编码的内容并写入a.txt文件中 |\n");
printf("\t | 2. 从文件中读取电文统计字母及频度 |\n");
if(exp[i]==ht[j].ch)
{
k=j;}
strcpy(p,hc[k].cd);
fputs(p,fp);
printf("%s",p);
}
fclose(fp);
printf("\t | 6. 从codefile.txt中读取编码并对其译码打印出来 |\n");
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#define maxval 1000
typedef struct{
char ch;
int weight;
int lchild,parent,rchild;
ht[i].rchild=0;
相关文档
最新文档