哈夫曼树的创建和编码
项目忙的要死,博客停了两天,做外包的真不好受,还是做产品的强。软件最后最值钱的不是代码,而是相关的文档,文档清楚,依葫芦画瓢照做出来应该不难。项目结束了至少要整理出需求规格说明书,系统设计文档,用户使用说明书,开发进度表,投标书,工作说明书等文档。
本文根据《数据结构与算法》(C语言版)(第三版) 整理。
哈夫曼树的构造过程示意图如下:
哈夫曼树的结点类型声明:
struct TreeNode
{
int weight;
int parent;
int lchild;
int rchild;
};
typedef struct TreeNode HFTreeNode;
typedef HFTreeNode HuffmanTree;
哈夫曼树的构造算法:
#define MaxSize 1000 //叶子数目
void Select(HuffmanTree *HT, int g, int &s1, int &s2);
void CreateHuffmanTree(HuffmanTree T[MaxSize], int n)
{
int i,p1,p2;
if(n<1)
return 1;
m=2*n; //计算哈夫曼树的结点大小
for(i=1; i
哈夫曼编码是在哈夫曼树的基础上求出来的,其基本思想是:从叶子结点di(0<=i
示例:对于字符集D={A,B,C,D},其频率(单位:千次)分布为F={12,6,2,18},下图给出D的哈夫曼编码图。
哈夫曼编码的回溯步骤如下:反序方法:首先将生成的编码从后向前依次存放在一个临时的一维数组中,并设一个指针start指示编码在该一维数组中的起始位置。当某个叶子结点的编码完成时,从临时的一维数组的start处将编码复制到该字符对应的bits中即可。
哈夫曼编码的存储结构: struct CodeNode
{
char ch; //存储字符
char bits[n+1]; //存放编码位串
};
typedef struct CodeNode CodeNoe;
typedef CodeNoe HUffmanCode[n];
哈夫曼编码的算法:
void CharSetHuffmanEncoding(HuffmanTree T, HuffmanCode H)
{ //根据哈夫曼树T求哈夫曼编码表H
int c, p, i;
char cd[n+1];
int start;
cd[n]='\0';
for(i=0; i0)
{
if(T[p].lchild==c)
{
cd[--start]='0';
}
else
{
cd[--start]='1';
}
c=p; //继续上溯
}
strcpy(H[i].bits, &cd[start]); //复制编码位串
}
}
算法如下:
void CharSetHuffmanDecoding(HuffmanTree T, char* cd, int n)
{
int p=2*n-2; //从根结点开始
int i=0;
//当要解码的字符串没有结束时
while(cd[i]!='/0')
{
//当还没有到达哈夫曼树的叶子并且要解码的字符串没有结束时
while((T[p].lchild!=0 && T[p].rchild != 0) && cd[i] != '\0')
{
if(cd[i] == '0')
{
//如果是0,则叶子在左子树
p=T[p].lchild;
}
else
{
//如果是1,则叶子在左子树
p=T[p].rchild;
}
i++;
}
//如果到达哈夫曼树的叶子时
if(T[p].lchild == 0 && T[p].rchild == 0)
{
printf("%c", T[p].ch);
p = 2*n-1;
}
else //如果编号为p的结点不是叶子,那么编码有错
{
printf("\n解码出错! \n");
return;
}
}
printf("\n");
}
// HuffmanTree.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include
#include
#include
typedef struct HuffmanTree
{
int weight;
int parent, lchild, rchild;
} HuffmanTree;
typedef struct CodeNode
{
int ch;
char bits[4+1];
}CodeNode;
void SelectMin(HuffmanTree tree[], int len, int * pos1, int* pos2)
{
int min=255;
int i, j;
*pos1=0;
*pos2=0;
for(i=0; itree[i].weight)
{
min=tree[i].weight;
*pos1=i;
}
}
min=255;
for(j=0; jtree[j].weight)
{
min=tree[j].weight;
*pos2=j;
}
}
}
void CreateHuffmanTree(HuffmanTree tree[], int n)
{
int m=2*n;
int i;
for(i=n; i
Ctrl+F5执行HuffmanTree.cpp结果如下图: