今天晚上花了好几个小时写了这个程序。。。都怪我效率太低。。。
好了废话不多说,下面就给出我的代码。(这个代码参考了 严蔚敏老师 的算法)
其中具体的实现就不多讲,因为我在注释都写了。
#include<iostream>
using namespace std;
struct hTNode{
unsigned int weight;
unsigned int parent,lchild,rchild;
};
typedef hTNode* huffTree;
//定义一个双重指针来存放Huffman编码
typedef char** huffCode;
//树上所有结点的个数
int cnt,i;
/**
* 选择权值最小的两个结点
* tree: 哈弗曼树
* n: 哈弗曼树上结点的个数
* s1,s2: 选出来的结果 ,即在树上的位置
*/
void select(huffTree tree, int n, int &s1, int &s2)
{
int i;
for(i = 2; i <= n; i ++)
{
if(tree[s1].parent != 0)
{
s1 = i;
continue;
}
if(tree[i].parent == 0)
if(tree[i].weight < tree[s1].weight)
s1 = i ;
}
for(i = 1; i <= n; i ++)
{
if(i == s1) continue;
if(s2 == s1 || tree[s2].parent != 0)
{
s2 = i;
continue;
}
if(tree[i].parent == 0)
if(s1 != s2 && tree[i].weight < tree[s2].weight)
s2 = i ;
}
}
/**
* 这个函数是本程序的最主要的函数,用来建立哈弗曼树,同时生成哈弗曼编码。
* n: 输入的数据的个数
* weight: 每个节点的权值
* tree: 哈弗曼树
* code: 哈弗曼编码
*/
void HuffEncoding(int n, int* weight, huffTree &tree, huffCode &codes)
{
int s1=1, s2=2;
huffTree p;
//如果输入的数据个数小于2,那么直接返回
if(n < 2) return;
cnt = 2*n - 1;
//申请这棵哈弗曼树的内存空间
tree = (huffTree)malloc((cnt+1)*sizeof(hTNode));
//把每一个录入的数据建成结点(或者说小树)
for(p = tree+1,i = 1; i <= n; ++i, ++p, ++weight)
{
p->weight = *weight;
p->lchild = 0;
p->rchild = 0;
p->parent = 0;
}
//初始化哈弗曼树上的每一个结点,先都设成0
for(;i <= cnt; ++i, ++p)
{
p->weight = 0;
p->lchild = 0;
p->rchild = 0;
p->parent = 0;
}
//开始建立哈弗曼树
for(i = n + 1; i <= cnt; ++ i)
{
select(tree, i-1, s1, s2);
tree[s1].parent = i;
tree[s2].parent = i;
tree[i].lchild = s1;
tree[i].rchild = s2;
tree[i].weight = tree[s1].weight + tree[s2].weight;
}
//开始求各个叶子结点的Huffman编码
{
char* cd;
int start,c,f=0;
codes = (huffCode)malloc((n+1)*sizeof(char*));
cd = (char*)malloc((n+1)*sizeof(char));
cd[n-1]='\0';
for(i = 1; i <= n; ++i)
{
start = n - 1;
for(c = i,f = tree[i].parent; f != 0;
c = f, f = tree[f].parent)
if(tree[f].lchild == c) cd[--start] = '0';
else cd[--start] = '1';
codes[i] = (char*)malloc((n - start)*sizeof(char));
strcpy(codes[i],&cd[start]);
}
free(cd);
}
}//HuffEncoding
int main()
{
int nn;
int* weight;
huffTree tree;
huffCode codes;
cout<<"Please input the count of the number:";
cin>>nn;
weight = (int*)malloc(nn*sizeof(int));
cout<<"Input the data one by one:"<<endl;
for(i = 0; i < nn; i ++)
{
cin>>weight[i];
}
HuffEncoding(nn,weight,tree,codes);
for(i = 1; i <= nn; i ++)
{
printf("%d:%s\n",tree[i].weight,codes[i]);
}
return 0;
}
分享到:
相关推荐
在C语言下实现哈弗曼树的创建并进行哈弗曼编码,同时输出哈弗曼编码。
### 哈弗曼树及哈弗曼编码的创建 #### 一、哈弗曼树的概念与构建 哈弗曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树,具有广泛的应用,特别是在数据压缩领域。其构造方法为:对给定的一...
2. **创建哈弗曼树**:基于这些频率,构建哈弗曼树。通常采用贪心算法,通过不断地合并频率最小的两个节点来构建。这个过程直到只剩下一个节点,即形成了哈弗曼树的根节点。 3. **生成编码**:从哈弗曼树的根节点...
哈弗曼编码(Huffman Coding)是基于哈弗曼树实现的一种变长编码方式,能够为不同的字符分配不同的二进制码,频率高的字符得到较短的编码,频率低的字符则得到较长的编码。 在C++中实现哈弗曼树和哈弗曼编码,主要...
哈弗曼树哈弗曼树哈弗曼树哈弗曼树哈弗曼树哈弗曼树哈弗曼树哈弗曼树哈弗曼树
哈弗曼编码是一种高效的数据压缩方法,它利用了字符出现频率的不同来构建最优的二叉树,也称为哈弗曼树。在这个C++程序中,我们将会深入理解哈弗曼编码的原理及其在实际编码过程中的应用。 首先,我们要知道哈弗曼...
哈弗曼树,又称霍夫曼树,是一种特殊的二叉树,主要用于数据的高效编码,尤其是在数据压缩领域有着广泛的应用。...在实际应用中,如在文件压缩软件中,哈弗曼编码常常与其他压缩技术结合使用,以达到更好的压缩效果。
哈弗曼树编码是一种...程序首先处理输入数据,计算字符频率,然后构建哈弗曼树,最后输出每个字符对应的哈弗曼编码。通过对这个源文件的学习和理解,读者可以深入掌握哈弗曼编码原理以及C语言和数据结构的实际应用。
在压缩包文件"2019302130093许美琪"中,可能包含了C语言实现的哈弗曼编码算法源代码,包括创建哈弗曼树、编码和解码的函数。通过阅读和理解这段代码,可以深入学习哈弗曼编码的实现细节,如如何构造最小堆、如何进行...
- **编码生成**:哈弗曼编码的生成是构建哈弗曼树的重要后续步骤,但给定代码并未涉及。 - **性能优化**:使用优先队列(如C++ STL中的`priority_queue`)替换循环查找最小权重节点的过程,可以显著提高构建哈弗曼树...
在本数据结构实习中,我们将深入理解哈弗曼编码的原理、构建过程及其应用,包括字符编码及译文的生成,以及哈弗曼树的动态演示。 哈弗曼编码的核心思想是为每个字符分配一个唯一的二进制码,使得频率高的字符编码...
哈弗曼编码是一种高效的数据压缩方法,它基于一种特殊的二叉树——哈弗曼树(Huffman Tree),也称为最优二叉树。在MFC(Microsoft Foundation Classes)框架下,我们可以构建用户界面来实现哈弗曼编码和解码的过程...
创建哈弗曼树的过程通常包括以下几个步骤: 1. **构建哈弗曼树的准备**:首先,我们需要收集所有需要编码的字符及其对应的频率(权重)。这些信息可以来自于文本或其他数据源。权重表示字符出现的次数或重要性,越...
哈弗曼树的构造过程主要包括两个主要步骤:哈弗曼编码和构建哈弗曼树。 1. **哈弗曼编码**: - 首先,统计每个字符(或数据元素)的频率,频率表示该字符在文本中的出现次数。 - 将每个字符视为一个带权重的节点...
- **压缩效率高**:对于具有不同频率的字符,哈弗曼编码可以实现较高的压缩率,尤其对于文本、图像等数据,能显著减少存储空间。 - **解压速度快**:由于编码规则固定,解压缩过程相对简单,速度较快。 - **适应性强...
4. **分配编码**:从根节点开始,遍历哈弗曼树,规定向左走为0,向右走为1,这样就能为每个叶子节点(即输入符号)生成一个唯一的二进制路径,也就是哈弗曼编码。 哈弗曼解码是根据哈弗曼树逆向进行的过程。当接收...
哈弗曼树的构建基于以下两个核心概念:哈弗曼编码(Huffman Coding)和带权路径长度(Weighted Path Length)。哈弗曼编码是一种前缀编码,即没有任何一个编码是另一个编码的前缀,这样可以避免在解码时产生歧义。...
- `HuffmanTreeInitialization`函数用于根据输入的权值表创建哈弗曼树。 - `Save_HuffmanTree`和`Lode_HuffmanTree`分别用于保存和加载哈弗曼树到文件。 - `HuffmanCode`类型用于存储编码表,`HuffmanCoding`函数...
- **编码**:从根节点出发,左分支代表0,右分支代表1,沿着哈弗曼树遍历到叶子节点,记录路径即可得到字符的哈弗曼编码。 - **解码**:根据编码表,反向操作,从编码出发,通过0和1的指引在哈弗曼树中找到对应的...
哈弗曼树,也称为最优二叉树,是通过哈弗曼编码实现数据压缩的关键工具。 哈弗曼树是一种特殊的二叉树,其特点是所有叶子节点(通常代表字符或数据元素)都在最底层,且没有左孩子节点的节点比有左孩子节点的节点离...