您的位置:首页 > 其它

赫夫曼树及赫夫曼编码

2016-11-20 19:53 246 查看

 以下面的例子来看一下

已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试编写算法求其赫夫曼编码。

#include<iostream>
#include<string.h>
#define UINT_iMAX 100
using namespace std;

typedef struct {
int weight;
int parent, lchild, rchild;
}HTNode, *HuffmanTree;

typedef char **HuffmanCode;

int Min(HuffmanTree &HT,int i)//用来求出森林中最小的两个节点
{
//在HT[1...i]中选择parent为0且权值最小的结点
//返回该结点的下标值
//此函数被Select函数调用
int j;
unsigned int k = UINT_iMAX;//假设各结点的权值不会超过UINT_MAX
int flag;
for(j = 1; j <= i; ++j)
{
if(HT[j].weight < k && HT[j].parent == 0)//用父结点是否为0来判断此结点是否已经被选过
{
k = HT[j].weight;
flag = j;
}
}
HT[flag].parent = 1;//作个标记,说明已经被选择了,因为在Select函数中要选择权值小的两个结点
return flag;
}

void Select(HuffmanTree &HT, int i, int &s1, int &s2)
{
//在HT[1...i]中选择parent为0且权值最小的两个结点,其序号分别为s1,s2
//s1 <= s2
s1 = Min(HT,i);
s2 = Min(HT,i);
}

void CreateHuffmanTree(HuffmanTree &HT, int n)
{
int m;
int i, s1, s2;
if(n<=1)//如果只有一个就不用创建
return ;
m=2*n-1; //总共需要2n-1个节点
HT=new HTNode[m+1];//开辟空间
for(i=1; i<=m; i++)//给所有的节点附初始值
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
cout<<"请分别输入"<<n<<"个权值:\n";
for(i=1; i<=n; i++)//输入你的n个节点权值
cin>>HT[i].weight;
cout<<"++++++++++++++";
for(i=n+1; i<=m; i++)
{
Select(HT, i-1,s1, s2);//在n个数中找出权值最小的两个

HT[s1].parent=i;
HT[s2].parent=i;//将他们两个的parent节点设置为i;
if(s1<s2)
{
HT[i].lchild=s1;
HT[i].rchild=s2;
}
else
{
HT[i].lchild=s2;
HT[i].rchild=s1;
}//把这两个分别当作左右节点
HT[i].weight=HT[s1].weight+HT[s2].weight;//他们两个的双亲为他们两个的和;

}
}

void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n)//赫夫曼编码函数
{
int start, c, f;
int i;
char *cd=new char
; //分配临时存放编码的动态数组空间
HC=new char*[n+1];//分配n个字符编码的头指针矢量

cd[n-1]='\0';
for(i=1; i<=n; i++)//倒序存放字符赫夫曼编码
{
start=n-1;// start开始时指向最后,即编码的结束符的位置
c=i;f=HT[i].parent;//f指向结点c的双亲结点

while(f!=0){//从叶子节点开始向上回溯,直到根节点
--start;
if(HT[f].lchild==c)
{
cd[start]='0';
}
else
{
cd[start]='1';
}
c=f;
f=HT[f].parent;
}
HC[i]=new char[n-start];//为第i个字符编码分配空间
strcpy(HC[i],&cd[start]);//将求得的编码从临时空间cd复制到HC的当前空间中
}
delete cd;//释放临时变量
}

int main()
{
HuffmanTree HT;
HuffmanCode HC;
cout<<"请输入权值的个数:\n";
int n, i;
cin>>n;
CreateHuffmanTree(HT, n);
CreatHuffmanCode(HT, HC, n);

cout<<"赫夫曼树为";
cout<<"++++++++++++++\n";
printf("NO\tweight\tparent\tlchild\trchild\n");
for(i=1; i <= 2*n-1; ++i)
{
printf("%d\t%d\t%d\t%d\t%d\n", i, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
}
printf("赫夫曼编码为:\n");
for(i = 1; i <= n; ++i)
printf("%d| |-->%s\n", i, HC[i]);
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: