导航:首页 > 源码编译 > 哈夫曼树需要实现的算法

哈夫曼树需要实现的算法

发布时间:2022-08-19 00:19:27

A. 哈夫曼树算法

题目的阐述:以N进制编码方式对一个英文字串中的字符进行编码,每个不同的字符其编码不同.使得由新的编码替代原串后总码长最小,且输入0,1,2,...,N-1构成的数字串后,依照该编码方式可以正确的对译出唯一的英文原串.如:N=3英文原串为ABBCBADDACE其对应的一种编码方式为A:00B:01C:020D:021E:022原串对译后的编码为000101020010002102100020022其码长为27若输入编码串0102002200则对应的英文原串为BCEA 分析: 假设英文原串中的字符存放于字符集S中,‖S‖=X,每个字符在字串中出现的概率为W[i],L[i]为字符i的编码长.依题意得,对S集合中的不同字符进行N进制编码后要求1)新字串的码长最短WPL=∑W[i]*L[i]
(i∈1..X)使得在WPL是所有编码方式中的最小值2)编码无二义性任意一字符编码都不为其它字符编码的前缀 此题以哈夫曼树来解答是非常适宜的.N为此哈夫曼树的分叉数,S字符集里的元素即为此N叉哈夫曼树的叶子,概率W[i]即为叶子结点的权重,从根结点到各叶子结点的路径长即为该叶子结点的编码长L[i].由哈夫曼树的思想可以知道哈夫曼树的建立是一步到位的贪心法,即权重越大的结点越靠近该树的根,这样,出现频率越大的字符其编码就越短.但具体应该怎样建立起此N叉哈夫曼树呢?我们首先以N=2为例:S={A,B,C,D}W=[3,1,2,1]首先从W中选出两个最小权,1,1,将其删去,并以2(即1+1)替代W=[3,2,2];再从新的W中取出两个最小权,2,2,将其删去,并以4(即2+2)替代W=[3,4];依此类推,直到W中只一个值时合并结束,此时W=[7]以上两两合并的过程即为二叉哈夫曼树的建立过程,每一次的合并即是将两棵子树归于一个根结点下,于是可以建立二叉树如下: m0åæ1mmA0åæ1mmC0åæ1mmBD MIN-WPL=3*1+1*3+2*2+1*3=13 从某一根结点出发走向其左子树标记为0,走向其右子树标记为1,则可以得到以下编码A,B,C,D对应的编码为A:0B:110C:10D:111
N=3时又是怎样一种情况呢?设S={A,B,C,D,E}W=[7,4,2,5,3}则按权重排序可得S={D,B,E,C,A}W=[7,5,4,3,2]那么此哈夫曼树的树形应为怎样呢?是以下的左图,还是右图,或是两者均不是mmåâæåæmmllmåæåæCAåælllllmADBEDåæ
lmBåællEC 显然,要带权路径长WPL最短,那么,此树的高度就应尽可能的小,由此可知将此树建成丰满N叉树是最合理的,于是我们尽量使树每一层都为N个分枝.对于这道题的情况,我们具体来分析.按照哈夫曼树的思想,首先从W中取出权最小的三个值,即2,3,4,并以9(2+3+4)来代替,得到新的W=[9,7,5];再将这三个值合并成9+7+5=21这个结点.于是得到三叉哈夫曼树如下:måâællmDBåâælllECAWPL=1*7+1*5+2*2+2*3+2*4=30以0..N-1依次标记每个根结点的N个分枝,则可以得到每个字符相对应的编码:A:22B:1C:21D:0E:20我们发现对于这种情况恰巧每层均为N个分枝,但事实上并非所有的N叉哈夫曼树都可得到每层N个分枝.例于当N=3,‖S‖=6时就不可能构成一棵每层都为三个分枝的三叉树.如何来处理这种情况呢?最简单的处理方式就是添加若干出现概率为0的空字符填补在N叉树的最下一层,这些权为0的虚结点并无实际意义但却非常方全便于这棵N叉树的建立.空字符的添加个数add的计算如下:Y=‖S‖mod(n-1)add=0(Y=1)add=1(Y=0)add=N-Y(Y>1) 虚结点的加入使得权重最小的N-add个字符构成了距根结点最远的分枝,使其它字符构成的N叉树保持了丰满的N叉结构.例:N=3S={A,B,C,D,E,F}W=[1,2,3,4,5,6}则y:=6mod(3-1)=0add=1于是构成N叉树如下:­为虚结点¡åâællmFEåâællmDCåâæBA­WPL=1*6+1*5+2*4+2*3+3*2+3*1+3*0=33对应编码为:A:221B:220C:21D:20E:1F:0

B. 哈夫曼的如何构造

然而怎样构造一棵哈夫曼树呢?最具有一般规律的构造方法就是哈夫曼算法。一般的数据结构的书中都可以找到其描述: 重复二和三两步,直到集合F中只有一棵二叉树为止。
用C语言实现上述算法,可用静态的二叉树或动态的二叉树。若用动态的二叉树可用以下数据结构: struct tree{
float weight; /*权值*/
union{
char leaf; /*叶结点信息字符*/
struct tree *left; /*树的左结点*/
};
struct tree *right; /*树的右结点*/
};
struct forest{ /*F集合,以链表形式表示*/
struct tree *ti; /* F中的树*/
struct forest *next; /* 下一个结点*/
};
例:若字母A,B,C,D出现的概率为:0.75,0.54,0.28,0.43;则相应的权值为:75,54,28,43。
构造好哈夫曼树后,就可根据哈夫曼树进行编码。例如:上面的字符根据其出现的概率作为权值构造一棵哈夫曼树后,经哈夫曼编码得到的对应的码值。只要使用同一棵哈夫曼树,就可把编码还原成原来那组字符。显然哈夫曼编码是前缀编码,即任一个字符的编码都不是另一个字符的编码的前缀,否则,编码就不能进行翻译。例如:a,b,c,d的编码为:0,10,110,111,对于编码串:1010就翻译为bb。刚才进行哈夫曼编码的规则是从根结点到叶结点(包含原信息)的路径,向左孩子前进编码为0,向右孩子前进编码为1,当然你也可以反过来规定。

C. 请描述哈夫曼算法,并用图描述构造哈夫曼树的过程。

这个讲的相当清楚。
首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为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中只有一棵二叉树为止。
用C语言实现上述算法,可用静态的二叉树或动态的二叉树。若用动态的二叉树可用以下数据结构: struct tree{
float weight; /*权值*/
union{
char leaf; /*叶结点信息字符*/
struct tree *left; /*树的左结点*/
};
struct tree *right; /*树的右结点*/
};
struct forest{ /*F集合,以链表形式表示*/
struct tree *ti; /* F中的树*/
struct forest *next; /* 下一个结点*/
};
例:若字母A,B,Z,C出现的概率为:0.75,0.54,0.28,0.43;则相应的权值为:75,54,28,43。
构造好哈夫曼树后,就可根据哈夫曼树进行编码。例如:上面的字符根据其出现的概率作为权值构造一棵哈夫曼树后,经哈夫曼编码得到的对应的码值。只要使用同一棵哈夫曼树,就可把编码还原成原来那组字符。显然哈夫曼编码是前缀编码,即任一个字符的编码都不是另一个字符的编码的前缀,否则,编码就不能进行翻译。例如:a,b,c,d的编码为:0,10,101,11,对于编码串:1010就可翻译为bb或ca,因为b的编码是c的编码的前缀。刚才进行哈夫曼编码的规则是从根结点到叶结点(包含原信息)的路径,向左孩子前进编码为0,向右孩子前进编码为1,当然你也可以反过来规定。
这种编码方法是静态的哈夫曼编码,它对需要编码的数据进行两遍扫描:第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并必须把树的信息保存起来,即把字符0-255(2^8=256)的频率值以2-4BYTES的长度顺序存储起来,(用4Bytes的长度存储频率值,频率值的表示范围为0--2^32-1,这已足够表示大文件中字符出现的频率了)以便解压时创建同样的哈夫曼树进行解压;第二遍则根据第一遍扫描得到的哈夫曼树进行编码,并把编码后得到的码字存储起来。 静态哈夫曼编码方法有一些缺点:一、对于过短的文件进行编码的意义不大,因为光以4BYTES的长度存储哈夫曼树的信息就需1024Bytes的存储空间;二、进行哈夫曼编码,存储编码信息时,若用与通讯网络,就会引起较大的延时;三、对较大的文件进行编码时,频繁的磁盘读写访问会降低数据编码的速度。
因此,后来有人提出了一种动态的哈夫曼编码方法。动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。动态哈夫曼编码比静态哈夫曼编码复杂的多,有兴趣的读者可参考有关数据结构与算法的书籍。
前面提到的JPEG中用到了哈夫曼编码,并不是说JPEG就只用哈夫曼编码就可以了,而是一幅图片经过多个步骤后得到它的一列数值,对这些数值进行哈夫曼编码,以便存储或传输。哈夫曼编码方法比较易懂,大家可以根据它的编码方法,自己编写哈夫曼编码和解码的程序。

D. 试编写实现哈夫曼树和哈夫曼编码的算法这是数据结构里的问题,要求用C++6.0来实现

#include <stdio.h>
#include <malloc.h>
#include<math.h>
struct hf
{
char data;
int weight;
struct hf *lc;
struct hf *rc;
struct hf *pc;
int hcd[30];
} *hc[30];
int n;

main()
{struct hf creat();
struct hf bian(struct hf *hc[30]);
struct hf print(struct hf *hc[30]);
int m;
do
{
printf("亲!请输入你所需要的功能:\n1代表构建哈夫曼树,2代表给哈夫曼树赋权值,3代表输出哈夫曼树的权值");
scanf("%d",&m);
switch(m)
{
case 1:creat();break;
case 2:bian(hc);break;
case 3:print(hc);break;

}
}while (m==1||m==2||m==3);

}

struct hf creat()
{
int i,m,k,p,t,r,u;
int selete (int k,struct hf *hc[30]);
printf("请输入你所需要构建哈夫曼树的个数:");
scanf("%d",&n);

for(i=0;i<n;i++)
{
getchar();
printf("请输入数据的符号");
hc[i]= (struct hf *)malloc(sizeof(struct hf));
scanf("%c",&hc[i]->data);
printf("请输入数据的权值:");
scanf("%d",&hc[i]->weight);
hc[i]->lc=0;
hc[i]->rc=0;
}
for(t=n;t<(2*n-1);t++)
{
hc[t]=(struct hf *)malloc(sizeof(struct hf));

}
for(u=0;u<(2*n-1);u++)
{
hc[u]->pc=0;
}

for(m=n;m<((2*n)-1);m++)
{ hc[m]->weight=0;
for(r=1;r<=2;r++)
{
p=selete(m,hc);
if(r==1)

{hc[m]->lc=hc[p];
hc[p]->pc=hc[m];

}
if(r==2)
{
hc[m]->rc=hc[p];
hc[p]->pc=hc[m];

}
hc[m]->weight=hc[m]->weight+hc[p]->weight;
}
}
}

int selete(int k,struct hf *hc[30])
{ int a,i,j;

for (i=0;i<k;)
{

if(hc[i]->pc!=0)

i++;

else
{
a=i;
for(j=i+1;j<k;)
{
if(hc[j]->pc!=0)
j++;
else if(hc[a]->weight>hc[j]->weight)
{
a=j;
j++;
}else j++;
}return (a);

}
}

}

struct hf bian(struct hf *hc[30])
{int i,m,t;
struct hf *p1,*p2;
for(i=0;i<n;i++)
{m=0;p1=hc[i];
while(p1->pc!=0)

{ p2=p1->pc;

if(p2->lc==p1)
{hc[i]->hcd[m]=0;
m++;
p1=p1->pc;
}
if(p2->rc==p1)
{ hc[i]->hcd[m]=1;
m++;
p1=p1->pc;
}

}
hc[i]->hcd[29]=m;
}

}

struct hf print(struct hf *hc[30])
{int i,p,m;

printf("其编码结果如下:\n");
for (i=0;i<n;i++)
{m=hc[i]->hcd[29];
for(p=m-1;p>=0;p--)
{printf("******* %c的哈夫曼编码为*******\n",hc[i]->data);
for(p=m-1;p>=0;p--)
printf(" %d ",hc[i]->hcd[p]);
printf("\n");
}
}

}

E. 数据结构的问题,求一个构造哈夫曼树的算法

void haffmantree(int weight[],int n,struct haffnode hafftree[],char data[])
/*建立叶结点个数为n,权值数组为weight[]的哈夫曼树*/
{int i,j,m1,m2,x1,x2;
/*哈夫曼树hafftree[]初始化,n个叶结点共有2n-1个结点*/
for(i=0;i<2*n-1;i++)
{if(i<n) {hafftree[i].data=data[i];
hafftree[i].weight=weight[i]; /*叶结点*/
}
else {hafftree[i].weight=0; /*非叶结点*/
hafftree[i].data='\0';
}
hafftree[i].parent=0; /*初始化没有双亲结点*/
hafftree[i].flag=0;
hafftree[i].leftchild=-1;
hafftree[i].rightchild=-1;
}
for(i=0;i<n-1;i++) /*构造哈夫曼树n-1个非叶结点*/
{m1=m2=MAXVALUE;
x1=x2=0;
for(j=0;j<n+i;j++)
{if(hafftree[j].weight<m1&&hafftree[j].flag==0)
{m2=m1;
x2=x1;
m1=hafftree[j].weight;
x1=j;
}
else if(hafftree[j].weight<m2&&hafftree[j].flag==0)
{m2=hafftree[j].weight;
x2=j;
}
}
hafftree[x1].parent=n+i;
hafftree[x2].parent=n+i;
hafftree[x1].flag=1;
hafftree[x2].flag=1;
hafftree[n+i].weight=hafftree[x1].weight+hafftree[x2].weight;
hafftree[n+i].leftchild=x1;
hafftree[n+i].rightchild=x2;

}
}
void haffmancode(struct haffnode hafftree[],int n,struct haffcode haffcode[])
{/*由n个结点的哈夫曼树hafftree[]构成的哈夫曼编码haffcode[]*/
int i,j,child,parent;
struct haffcode newcode;
struct haffcode *cd;
cd=&newcode;
for(i=0;i<n;i++) /*求n个结点的哈夫曼编码*/
{cd->start=MAXBIT-1; /*不等长编码的最后一位是n-1*/
cd->weight=hafftree[i].weight;
cd->data=hafftree[i].data; /*取得编码对应值的字符*/
child=i;
parent=hafftree[child].parent;
while(parent!=0)
{if(hafftree[parent].leftchild==child)
cd->bit[cd->start]=0; /*左孩子编码为0*/
else
cd->bit[cd->start]=1; /*右孩子编码为1*/
cd->start--;
child=parent;
parent=hafftree[child].parent;
}
for(j=cd->start+1;j<MAXBIT;j++) /*保存每个叶结点的编码和等长编码的起始位*/
haffcode[i].bit[j]=cd->bit[j];
haffcode[i].data=cd->data;
haffcode[i].start=cd->start;
haffcode[i].weight=cd->weight;
}
}

F. 哈夫曼树及哈夫曼编码的C程序实现(数据结构题)

去年做的课程设计,有什么不合要求的自己改改

#include<string.h>
#include<stdlib.h>
#include<stdio.h>

int m,s1,s2;

typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树
typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表

void Select(HuffmanTree HT,int n) {
int i,j;
for(i = 1;i <= n;i++)
if(!HT[i].parent){s1 = i;break;}
for(j = i+1;j <= n;j++)
if(!HT[j].parent){s2 = j;break;}
for(i = 1;i <= n;i++)
if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))s1=i;
for(j = 1;j <= n;j++)
if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))s2=j;
}

void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[], int *w, int n) {
// 算法6.13
// w存放n个字符的权值(均>0),构造哈夫曼树HT,
// 并求出n个字符的哈夫曼编码HC
int i, j;
char *cd;
int p;
int cdlen;

if (n<=1) return;
m = 2 * n - 1;
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元未用
for (i=1; i<=n; i++) { //初始化
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for (i=n+1; i<=m; i++) { //初始化
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
puts("\n哈夫曼树的构造过程如下所示:");
printf("HT初态:\n 结点 weight parent lchild rchild");
for (i=1; i<=m; i++)
printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,
HT[i].parent,HT[i].lchild, HT[i].rchild);
printf(" 按任意键,继续 ...");
getchar();
for (i=n+1; i<=m; i++) { // 建哈夫曼树
// 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
// 其序号分别为s1和s2。
Select(HT, i-1);
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;
printf("\nselect: s1=%d s2=%d\n", s1, s2);
printf(" 结点 weight parent lchild rchild");
for (j=1; j<=i; j++)
printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,
HT[j].parent,HT[j].lchild, HT[j].rchild);
printf(" 按任意键,继续 ...");
getchar();
}

//------无栈非递归遍历哈夫曼树,求哈夫曼编码
cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间
p = m; cdlen = 0;
for (i=1; i<=m; ++i) // 遍历哈夫曼树时用作结点状态标志
HT[i].weight = 0;
while (p) {
if (HT[p].weight==0) { // 向左
HT[p].weight = 1;
if (HT[p].lchild != 0) { p = HT[p].lchild; cd[cdlen++] ='0'; }
else if (HT[p].rchild == 0) { // 登记叶子结点的字符的编码
HC[p] = (char *)malloc((cdlen+1) * sizeof(char));
cd[cdlen] ='\0'; strcpy(HC[p], cd); // 复制编码(串)
}
} else if (HT[p].weight==1) { // 向右
HT[p].weight = 2;
if (HT[p].rchild != 0) { p = HT[p].rchild; cd[cdlen++] ='1'; }
} else { // HT[p].weight==2,退回退到父结点,编码长度减1
HT[p].weight = 0; p = HT[p].parent; --cdlen;
}
}
} // HuffmanCoding
void main() {
HuffmanTree HT;HuffmanCode *HC;int *w,n,i;
puts("输入结点数:");
scanf("%d",&n);
HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
w = (int *)malloc(n*sizeof(int));
printf("输入%d个结点的权值\n",n);
for(i = 0;i < n;i++)
scanf("%d",&w[i]);
HuffmanCoding(HT,HC,w,n);
puts("\n各结点的哈夫曼编码:");
for(i = 1;i <= n;i++)
printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
getchar();
}

G. 哈夫曼算法

计算过程如图所示:

H. 哈夫曼树的构造算法

/*-------------------------------------------------------------------------
*Name:哈夫曼编码源代码。
*Date:2011.04.16
*Author:JeffreyHill+Jezze(解码部分)
*在Win-TC下测试通过
*实现过程:着先通过HuffmanTree()函数构造哈夫曼树,然后在主函数main()中
*自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在
*父结点左侧,则置码为0,若在右侧,则置码为1。最后输出生成的编码。
*------------------------------------------------------------------------*/
#include<stdio.h>
#include<stdlib.h>

#defineMAXBIT100
#defineMAXVALUE10000
#defineMAXLEAF30
#defineMAXNODEMAXLEAF*2-1

typedefstruct
{
intbit[MAXBIT];
intstart;
}HCodeType;/*编码结构体*/
typedefstruct
{
intweight;
intparent;
intlchild;
intrchild;
intvalue;
}HNodeType;/*结点结构体*/

/*构造一颗哈夫曼树*/
voidHuffmanTree(HNodeTypeHuffNode[MAXNODE],intn)
{
/*i、j:循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,
x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/
inti,j,m1,m2,x1,x2;
/*初始化存放哈夫曼树数组HuffNode[]中的结点*/
for(i=0;i<2*n-1;i++)
{
HuffNode[i].weight=0;//权值
HuffNode[i].parent=-1;
HuffNode[i].lchild=-1;
HuffNode[i].rchild=-1;
HuffNode[i].value=i;//实际值,可根据情况替换为字母
}/*endfor*/

/*输入n个叶子结点的权值*/
for(i=0;i<n;i++)
{
printf("Pleaseinputweightofleafnode%d: ",i);
scanf("%d",&HuffNode[i].weight);
}/*endfor*/

/*循环构造Huffman树*/
for(i=0;i<n-1;i++)
{
m1=m2=MAXVALUE;/*m1、m2中存放两个无父结点且结点权值最小的两个结点*/
x1=x2=0;
/*找出所有结点中权值最小、无父结点的两个结点,并合并之为一颗二叉树*/
for(j=0;j<n+i;j++)
{
if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1)
{
m2=m1;
x2=x1;
m1=HuffNode[j].weight;
x1=j;
}
elseif(HuffNode[j].weight<m2&&HuffNode[j].parent==-1)
{
m2=HuffNode[j].weight;
x2=j;
}
}/*endfor*/
/*设置找到的两个子结点x1、x2的父结点信息*/
HuffNode[x1].parent=n+i;
HuffNode[x2].parent=n+i;
HuffNode[n+i].weight=HuffNode[x1].weight+HuffNode[x2].weight;
HuffNode[n+i].lchild=x1;
HuffNode[n+i].rchild=x2;

printf("x1.weightandx2.weightinround%d:%d,%d ",i+1,HuffNode[x1].weight,HuffNode[x2].weight);/*用于测试*/
printf(" ");
}/*endfor*/
/*for(i=0;i<n+2;i++)
{
printf("Parents:%d,lchild:%d,rchild:%d,value:%d,weight:%d ",HuffNode[i].parent,HuffNode[i].lchild,HuffNode[i].rchild,HuffNode[i].value,HuffNode[i].weight);
}*///测试
}/*endHuffmanTree*/

//解码
voiddecodeing(charstring[],HNodeTypeBuf[],intNum)
{
inti,tmp=0,code[1024];
intm=2*Num-1;
char*nump;
charnum[1024];
for(i=0;i<strlen(string);i++)
{
if(string[i]=='0')
num[i]=0;
else
num[i]=1;
}
i=0;
nump=&num[0];

while(nump<(&num[strlen(string)]))
{tmp=m-1;
while((Buf[tmp].lchild!=-1)&&(Buf[tmp].rchild!=-1))
{

if(*nump==0)
{
tmp=Buf[tmp].lchild;
}
elsetmp=Buf[tmp].rchild;
nump++;

}

printf("%d",Buf[tmp].value);
}


}


intmain(void)
{

HNodeTypeHuffNode[MAXNODE];/*定义一个结点结构体数组*/
HCodeTypeHuffCode[MAXLEAF],cd;/*定义一个编码结构体数组,同时定义一个临时变量来存放求解编码时的信息*/
inti,j,c,p,n;
charpp[100];
printf("Pleaseinputn: ");
scanf("%d",&n);
HuffmanTree(HuffNode,n);


for(i=0;i<n;i++)
{
cd.start=n-1;
c=i;
p=HuffNode[c].parent;
while(p!=-1)/*父结点存在*/
{
if(HuffNode[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--;/*求编码的低一位*/
c=p;
p=HuffNode[c].parent;/*设置下一循环条件*/
}/*endwhile*/

/*保存求出的每个叶结点的哈夫曼编码和编码的起始位*/
for(j=cd.start+1;j<n;j++)
{HuffCode[i].bit[j]=cd.bit[j];}
HuffCode[i].start=cd.start;
}/*endfor*/

/*输出已保存好的所有存在编码的哈夫曼编码*/
for(i=0;i<n;i++)
{
printf("%d'sHuffmancodeis:",i);
for(j=HuffCode[i].start+1;j<n;j++)
{
printf("%d",HuffCode[i].bit[j]);
}
printf("start:%d",HuffCode[i].start);

printf(" ");

}
/*for(i=0;i<n;i++){
for(j=0;j<n;j++)
{
printf("%d",HuffCode[i].bit[j]);
}
printf(" ");
}*/
printf("Decoding?PleaseEntercode: ");
scanf("%s",&pp);
decodeing(pp,HuffNode,n);
getch();
return0;
}

http://www.cnblogs.com/Jezze/archive/2011/12/23/2299884.html

I. 数据结构哈夫曼树的算法

每次取最小的2个合并后的值继续加入集合进行比较,直到集合里只有一个数为止,这样就可以达到权值最小的路径越长,权值越大的路径越短,即可以找到最小权值路径

阅读全文

与哈夫曼树需要实现的算法相关的资料

热点内容
哪个网站可以看岛国片 浏览:648
代驾app如何导航到起点 浏览:667
机器人穿越外国电影 浏览:681
赢在龙头主图指标源码 浏览:951
符号加在命令后面 浏览:271
沙漏验机宝检测安卓手机怎么样 浏览:369
非洲电影有哪些好看的 浏览:763
媒介学pdf 浏览:234
推荐一个在线观看 浏览:471
单片机16进制编程图 浏览:490
金刚2迅雷下载 浏览:275
聚优电影卡使用范围 浏览:760
浙江网络卫星授时服务器云空间 浏览:497
宝塔加密方式 浏览:217
linux环境变量的路径 浏览:749
粉笔缓存的视频在手机哪个文件夹 浏览:680
港片尺度大 浏览:373
女主胸大的H电影 浏览:877
小女孩那个电影叫什么 浏览:58