根据网上的相关资料,通过构造哈夫曼树求解最优二叉树所有叶子结点的带权路径长度之和
# include<stdio.h>
#include<malloc.h>
#define maxsize 30;
/*
霍夫曼树求解最佳二叉树
完成时间:2015-7-10
*/
typedef struct ptree
{
float w;
struct ptree *lchild;
struct ptree *rchild;
}ptree,*ptt;//二叉树定义,w为权值
typedef struct pforest
{
struct pforest *link;
struct ptree *root;
}pforest;//森林定义。
float WPL=0;
int n=0;
struct pforest *inforest(struct pforest *f,struct ptree *t)
{
//根据权值的大小将二叉树一个个放到森林里。即将t插入该森林
struct pforest *p,*q,*r;
struct ptree *ti;
//开辟新的空间,便于插入至森林
r=(pforest *)malloc(sizeof(pforest));
r->link=NULL;
r->root=t;
q=f;
p=f->link;
while(p!=NULL)
{
ti=p->root;//取出此树的根节点
if(t->w>ti->w)
{
q=p;
p=p->link;
}
else
p=NULL;
}//while
r->link=q->link;
q->link=r;//插入新的二叉树
return f;
}
struct ptree *hafm(float w[])
{
pforest *p1,*p2,*f;
ptree *t,*t1,*t2;//用于保存取出来的两个节点
ptree *ti;//新节点
int i;
f=(pforest *)malloc(sizeof(pforest));
f->link=NULL;
// printf("%d ",n);
for(i=0;i<n;i++)
{
ti=(ptree*)malloc(sizeof(ptree));
ti->w=w[i];
ti->lchild=NULL;
ti->rchild=NULL;
// printf("%d ",i);
f=inforest(f,ti);//将ti挂到一棵树上面,初试化的时候形成了n颗树。
}//初始化
// printf("\n");
while(((f->link)->link)!=NULL)//f为一颗森林,如果至少含有两棵树则继续进行
{
p1=f->link;
p2=p1->link;
//f为一有序链表,取出前2颗二叉树。
f->link=p2->link;
t1=p1->root;//取出树
t2=p2->root;
free(p1);
free(p2);
//接着形成新的节点
t=(ptree*)malloc (sizeof(ptree));
t->w=(t1->w)+(t2->w);
t->lchild=t1;
t->rchild=t2;//产生新的二叉树
f=inforest(f,t);//挂到树上
}
p1=f->link;
t=p1->root;//保存最终二叉树
free(f);//此时为最终情况,即最终的二叉树,*/
return t;
}
void Input_Node(float w[])
{
printf("Please Input the sum of node:\n");
scanf("%d",&n);
printf("请依次输入权重值:\n");
for(int i=0;i<n;i++)
{
scanf("%f",&w[i]);
}
}//正常
void travel(struct ptree *head,int num)
{
struct ptree *p;
p=head;
if(p!=NULL)
{
if(((p->lchild)==NULL)&&((p->rchild)==NULL))
{
// printf("%lf",p->w);
// printf("\n");
WPL=WPL+num*(p->w);
}
travel(p->lchild,num+1);
travel(p->rchild,num+1);//
}
}
void main ()
{
struct ptree *head;
float w[20];
Input_Node(w);
head=hafm(w);
travel(head,0);
printf("\n最优二叉树所有叶子结点的带权路径长度之和:%lf\n",WPL);
n=0;
}
附图一张: