哈弗曼二叉樹的C簡單實現

#include
#include<malloc.h>
#define m 100
struct ptree              //定義二叉樹結點類型  
  
{  
  
int w;                   //定義結點權值  
  
struct ptree *lchild;     //定義左子結點指針  
  
struct ptree *rchild;     //定義右子結點指針  
  
};  
  
   
  
struct pforest              //定義鏈表結點類型  
  
{  
  
struct pforest *link;  
  
struct ptree *root;  
  
};  
  
   
  
int WPL=0;                  //初始化WTL爲0  
  
struct ptree *hafm();  
  
void travel();  
  
struct pforest *inforest(struct pforest*f,struct ptree *t);  
  
   
  
void travel(struct ptree *head,int n)                      
  
{  
  
//爲驗證harfm算法的正確性進行的遍歷  
  
struct ptree *p;  
  
p=head;  
  
if(p!=NULL)  
  
 {  
  
      if((p->lchild)==NULL && (p->rchild)==NULL) //如果是葉子結點  
  
     {  
  
             printf("%d ",p->w);  
  
             printf("the hops of the node is: %d\n",n);  
  
      WPL=WPL+n*(p->w);    //計算權值  
  
        }//if  
  
travel(p->lchild,n+1);  
  
travel(p->rchild,n+1);  
  
}//if  
  
}//travel  
  
   
  
struct ptree *hafm(int n, int w[m])  
  
{  
  
struct pforest *p1,*p2,*f;  
  
struct ptree *ti,*t,*t1,*t2;  
  
int i;  
  
f=(pforest *)malloc(sizeof(pforest));  
  
f->link=NULL;  
  
for(i=1;i<=n;i++)          //產生n棵只有根結點的二叉樹  
  
  {  
  
      ti=(ptree*)malloc(sizeof(ptree));//開闢新的結點空間  
  
   ti->w=w[i];               //給結點賦權值  
  
   ti->lchild=NULL;  
  
   ti->rchild=NULL;  
  
   f=inforest(f, ti);  
  
      //按權值從小到大的順序將結點從上到下地掛在一顆樹上       
  
 }//for  
  
while(((f->link)->link)!=NULL)//至少有二棵二叉樹  
  
  {  
  
 p1=f->link;  
  
 p2=p1->link;  
  
 f->link=p2->link;           //取出前兩棵樹  
  
 t1=p1->root;  
  
 t2=p2->root;  
  
 free(p1);                 //釋放p1  
  
 free(p2);                 //釋放p2  
  
 t=(ptree *)malloc(sizeof(ptree));//開闢新的結點空間  
  
 t->w = (t1->w)+(t2->w);        //權相加  
  
 t->lchild=t1;  
  
 t->rchild=t2;             //產生新二叉樹  
  
 f=inforest(f,t);  
  
 }//while  
  
 p1=f->link;  
  
 t=p1->root;  
  
 free(f);  
  
 return(t);                  //返回t  
  
 }  
  
   
  
pforest *inforest(struct pforest *f,struct ptree *t)  
  
{  
  
//按權值從小到大的順序將結點從上到下地掛在一顆樹上       
  
struct pforest *p, *q, *r;  
  
struct ptree *ti;  
  
r=(pforest *)malloc(sizeof(pforest)); //開闢新的結點空間  
  
r->root=t;  
  
q=f;  
  
p=f->link;               
  
while (p!=NULL)            //尋找插入位置  
  
 {  
  
  ti=p->root;  
  
  if((t->w)>(ti->w))         //如果t的權值大於ti的權值  
  
     {  
  
        q=p;  
  
     p=p->link;             //p向後尋找  
  
    }//if  
  
  else  
  
      p=NULL;                  //強迫退出循環  
  
 }//while  
  
r->link=q->link;  
  
q->link=r;                 //r接在q的後面  
  
return(f);                 //返回f  
  
}  
  
   
  
void InPut(int &n,int w[m])  
  
{  
  
printf("please input the sum ofnode\n"); //提示輸入結點數  
  
scanf("%d",&n);      //輸入結點數  
  
printf ("please input weight of everynode\n"); //提示輸入每個結點的權值  
  
for(int i=1;i<=n;i++)  
{
  printf ("please input weight of node %d\n",i); //提示輸入每個結點的權值  
scanf("%d",&w[i]);  //輸入每個結點權值  
}
  
}  
  
   
  
int main( )  
  
{  
  
struct ptree *head;  
  
int n,w[m];  
  
InPut(n,w);  
  
head=hafm(n,w);  
  
travel(head,0);  
  
printf("The length of the best path isWPL=%d", WPL);//輸出最佳路徑權值之和  
int j;
  scanf("%d",&j); 
return 1;  
  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章