huffman树入门
这段代码是对数学结构课本上的huffman树的一个简单优化。基本操作不变,对于一些错误进行了更正。并且化繁为简,改掉了一些冗长的代码。并且在个别地方进行修改,且对重要之处加以注释,以增强代码的可读性。配了一张自己做的小图。
参考书目《数据结构(c语言版)》中国水利水电出版社 主编:赵坚
#include "stdio.h"
#include "stdlib.h"
#define m 100
typedef struct ptree /*包含权值,左右子树的二叉树结构*/
{
int weight;
struct ptree *lchild,*rchild;
}pTree;
typedef struct pforest /*以二叉树为成员的森林结构*/
{
struct pforest *link;
pTree *root;
}pForest;
int WPL=0;
pForest *inforest(pForest *f,pTree *t) /*将树从小到大排序组成森林*/
{
pForest *q,*p,*r;
pTree *pt;
r=(pForest *)malloc(sizeof(pForest));
r->root =t;
q=f;
p=f->link ;
while(p!=NULL) /*寻找插入位置,每次保证从小到大*/
{
pt=p->root ;
if(t->weight >pt->weight )
{
q=p;
p=p->link ;
}
else
break; /*为了使循环终止*/
/*p=NULL; 也可以。 p=NULL并不会对原来的森林结构造成影响,p只是个指针*/
}
r->link =q->link ;
q->link =r;
return f;
}
pTree *hufm(int n,int w[m])
{
pForest *p1,*p2,*f;
pTree *t1,*t2,*t,*pt;
int i;
f=(pForest *)malloc(sizeof(pForest));
f->link =NULL;
for(i=1;i<=n;i++) /*产生n棵只有根结点的二叉树*/
{
pt=(pTree *)malloc(sizeof(pTree)); /*开辟新的结点空间*/
pt->weight =w[i]; /*对结点赋权值*/
pt->lchild =NULL; /*指针初始化为空*/
pt->rchild =NULL;
f=inforest(f,pt);
}
while((f->link )->link !=NULL)
{
p1=f->link ;
p2=p1->link;
f->link =p2->link ;
t1=p1->root ;
t2=p2->root ;
free(p1);
free(p2);
t=(pTree *)malloc(sizeof(pTree));
t->weight =t1->weight +t2->weight ;
t->lchild =t1;
t->rchild =t2;
f=inforest(f,t);
}
/*以下操作彻底删除森林结构的痕迹,因为haffman树已经成型*/
p1=f->link ;
t=p1->root ;
free(f);
return(t);
}
void travel(pTree *head,int n) /*先序遍历huffman树*/
{
pTree *p;
p=head;
if(p!=NULL)
{
if(p->lchild ==NULL&&p->rchild ==NULL)
{
printf("结点权值为%d的路径长度为:%d\n",p->weight ,n);
WPL=WPL+n*(p->weight ); /*计算权值*/
}
travel(p->lchild ,n+1);
travel(p->rchild ,n+1);
}
}
int main()
{
pTree *head;
int n;
int i,w[m];
printf("请输入结点总数\n");
scanf("%d",&n);
printf("请输入每个结点的权值\n");
for(i=1;i<=n;i++)
scanf("%d",&w[i]);
head=hufm(n,w);
travel(head,0);
printf("最佳路径的权值之和为%d\n",WPL);
}
浙公网安备 33010602011771号