共有回帖数 0 个
-
#include stdio.h
#include stdlib.h
#define MaxSize 50
typedef struct{
char c; //代码;
int w; //代码权值;
char code[MaxSize]; //代码的Huffman编码;
}HuffCode[MaxSize];
typedef struct{
int Weight; //权值;
int LChild,RChild,Parent;
}HTNode,HuffTree[MaxSize];
//================================================================================
void HuffmanTree(HuffTree HT,int length,HuffCode hc); //生成Huffman树;
void SelectHTNode(HuffTree HT,int n,int *min1,int *min2); //查找最小和次小序号;
void HuffmanCode(HuffTree HT,int len,HuffCode hc); //生成Huffman编码;
//================================================================================
int main(void)
{
HuffTree HT; //Huffman树;
HuffCode HC; //Huffman编码;
int i,len;
printf(" Huffman编码生成程序 ttby Haroldi.nn 请帮助评价一下思路及改善意见!t多谢了:-)...nnnn");
printf("n输入代码数量:"); scanf("%d",&len); system("cls");printf("代码数量:%2dnn",len);
printf("输入代码及权值(e.g.: "a16[回车]" ):n");
for(i=1;i = len;i++)
{
while(getchar() != 'n') NULL;
printf("No.%2d: ",i);
HC.c = getchar();
scanf("%d",&HC.w);
}
HuffmanTree(HT,len,HC);
HuffmanCode(HT,len,HC);
printf("n输出Huffman编码:n");
for(i = 1;i=len;i++)
{
printf("n %c :",HC.c);
puts(HC.code);
}
//测试Huffman树结构;
printf("nn输出Huffman树结构:");system("pause");
printf("nHT:t权值t双亲t左孩子t右孩子n");
for(i = 1;i2*len;i++)
{
if(i = len) printf("(%c)",HC.c);
printf("%2d:t %2d;t%2d,t %2d,t %2d.n",
i,HT.Weight,HT.Parent,HT.LChild,HT.RChild);
}
return 0;
}
//================================================================================
void HuffmanTree(HuffTree HT,int length,HuffCode hc) //Huffman树初始化;
{
int i,min1,min2;
HT[0].Weight = 65535;
for(i = 1;i = length;i++)
{
HT.Weight = hc.w;
HT.LChild = HT.RChild = HT.Parent = -1;
}
for(;i 2*length;i++) //i初值 = length+1;
{
HT.LChild = HT.RChild = HT.Parent = -1;
}
for(i = length+1;i 2*length;i++)
{
SelectHTNode(HT,i,&min1,&min2);
HT[min1].Parent = i;
HT[min2].Parent = i;
HT.LChild = min1;
HT.RChild = min2;
HT.Weight = HT[min1].Weight + HT[min2].Weight;
}
}
//================================================================================
void SelectHTNode(HuffTree HT,int n,int *min1,int *min2) //查找最小和次小序号;
{
int i;
*min1 = *min2 = 0;
for(i = 1;i n;i++)
{
if(HT.Parent == -1)
{
if(HT[*min1].Weight = HT.Weight)
{
*min2 = *min1;
*min1 = i;
}
else if(HT[*min2].Weight HT.Weight) *min2 = i;
}
}
}
//================================================================================
void HuffmanCode(HuffTree HT,int len,HuffCode hc) //生成Huffman编码;
{
int i,j,tc,Stack[MaxSize],top = -1;
char flag[MaxSize];
HTNode th;
for(i = 1;i = len;i++)
{
top = -1; //栈初始化;
j = 0; //hc.code串首位置偏移;
th = HT; //当前结点th;
tc = i; //当前结点标记tc;
while(th.Parent != -1)
{ //当前结点th双亲P入栈,由P的孩子是th,确定flag;确定下次结点标记tc;
Stack[++top] = th.Parent;
if(HT[th.Parent].LChild == tc) {flag[top] = 'L'; tc = th.Parent;}
if(HT[th.Parent].RChild == tc) {flag[top] = 'R'; tc = th.Parent;}
th = HT[Stack[top]]; //下一结点;
}
while(top != -1)
{
if(flag[top] == 'L') hc.code[j++] ='0';
else hc.code[j++] ='1';
Stack[top--]; //出栈;
}
hc.code[j] =' '; //当前串结束;
}
}
//================================================================================
哈夫曼树
在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN)树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如JPEG中就应用了哈夫曼编码。
首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。它是一种变长的编码。在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。(注:码字即为符号经哈夫曼编码后得到的编码,其长度是因符号出现的概率而不同,所以说哈夫曼编码是变长的编码。)
然而怎样构造一棵哈夫曼树呢?最具有一般规律的构造方法就是哈夫曼算法。一般的数据结构的书中都可以找到其描述:
一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。)
二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,直到集合F中只有一棵二叉树为止��
楼主 2016-01-08 11:00 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知