天天看點

赫夫曼樹列印(TC2.0)

/*<<<---------------------------------------------------------------------------------------------->>>*/

/*<<<

**<<< Programme Name : Huffman Tree Print

**<<< IDE : TC2.0

**<<< Author : Cifry

**<<< Create Date : 2007.08.23

**<<< New Amend : 2007.08.25

**<<< QQ : 442044866

**<<< Email :[email protected]

**<<< Say :

**<<< 請在目前目錄下建立一個名為“read.txt”的文本檔案,該檔案為資料讀入

**<<< 檔案。在“read.txt”中輸入資料,格式為[節點辨別][權]為一個節點(其中不

**<<< 不含空格,各節點間用空格分開(空格可任意多少) ,請在檔案最後輸入

**<<< “#”作為資料讀取的結束标志。如:

**<<< a10 b2 c7 d3 e9 f40 j5 h123 i77 j6 k19 l22 m47 n24 o4 p11 #

**<<< 程式運作後将讀取“read.txt”中資料,并将處理結果輸出到建立在目前目

**<<< 錄的“Print.txt”檔案中。輸出結果使用樹型結構列印,形象易懂。

**<<<

**<<< Copyright(c)Cifry

<<<*/

/*<<<---------------------------------------------------------------------------------------------->>>*/

#include<stdio.h>

struct HufNode

{

char ID;

unsigned weight;

struct HufNode *lchild;

struct HufNode *rchild;

struct HufNode *parent;

};/*霍夫曼樹節點*/

struct Volume_Bintree

{

struct HufNode *Tree;

struct Volume_Bintree *Next;

};/*二叉樹集合節點(森林)*/

FILE *rfp,*wfp;

/*将檔案中的資料做成二叉樹集合*/

struct Volume_Bintree *ReadBintree()

{

struct Volume_Bintree *Forest =NULL;

struct Volume_Bintree *FCreater =NULL;

struct HufNode *HCreater =NULL;

Forest=(struct Volume_Bintree *)malloc(sizeof(struct Volume_Bintree));

Forest->Next=NULL;

FCreater=Forest;

while(1)

{

char ID;

while((ID=getc(rfp))==' '); /*尋找下一個二叉樹資料的起始位置*/

if(ID=='#')break;/* # 為檔案的結束标志*/

HCreater=(struct HufNode *)malloc(sizeof(struct HufNode));

HCreater->parent=NULL;

HCreater->lchild=NULL;

HCreater->rchild=NULL;

FCreater->Next=(struct Volume_Bintree *)malloc(sizeof(struct Volume_Bintree));

FCreater->Tree=HCreater;/*将讀入的二叉樹存入森林*/

HCreater->ID=ID;

fscanf(rfp,"%u",&HCreater->weight);

FCreater=FCreater->Next;

FCreater->Next=NULL;

}

FCreater=Forest; /*清除最後一個無用元素*/

while(FCreater->Next->Next!=NULL){FCreater=FCreater->Next;}

free(FCreater->Next->Next);

FCreater->Next=NULL;

return Forest;

}

/*構造霍夫曼樹*/

struct HufNode *CreateHuf(struct Volume_Bintree *Forest)

{

struct Volume_Bintree *Comp =NULL;

struct Volume_Bintree *Min1 =NULL;

struct Volume_Bintree *Min2 =NULL;

struct HufNode *Tree1 =NULL;

struct HufNode *Tree2 =NULL;

while(1)

{

{/*獲得二叉樹集合中的最小權值的節點并在集合中清除該節點*/

Min1=Forest;/*二叉樹集合的第一個二叉樹給Min1*/

Comp=Forest;

while(Comp->Next!=NULL)/*查找權值最小的二叉樹的字首二叉樹*/

{

if(Min1->Tree->weight > Comp->Next->Tree->weight)

Min1=Comp->Next;

Comp=Comp->Next;

}

if(Min1!=Forest)

{

Comp=Forest;

while(Comp->Next!=Min1){Comp=Comp->Next;}

}

Tree1=Min1->Tree;

if(Min1==Forest)/*第一個二叉樹是二叉樹集合的最小權值的二叉樹*/

{

Forest=Min1->Next;

Tree1=Min1->Tree;

}

else if(Min1->Next==NULL)/*最後一個二叉樹是二叉樹集合的最小權值的二叉樹*/

{

Comp->Next=Min1->Next;

}

else

{

Comp->Next=Min1->Next;

}

free(Min1);

}

/*繼續從二叉樹集合中獲得最小權值的二叉樹*/

{

Min2=Forest;

Comp=Forest->Next;

while(Comp!=NULL)/*查找權值最小的二叉樹*/

{

if(Min2->Tree->weight > Comp->Tree->weight)

Min2=Comp;

Comp=Comp->Next;

}

Tree2=Min2->Tree;

}

Min2->Tree=(struct HufNode *)malloc(sizeof(struct HufNode));

Min2->Tree->lchild=Tree1;/*構造左子樹*/

Tree1->parent=Min2->Tree;

Min2->Tree->rchild=Tree2;/*構造右子樹*/

Tree2->parent=Min2->Tree;

Min2->Tree->ID='+';

Min2->Tree->weight=Tree1->weight+Tree2->weight;

if(Forest->Next==NULL) break;

}

return (struct HufNode *)Forest->Tree;

}

/*列印樹*/

/*該函數稍加修改可以列印任何形式的樹*/

/*flag 為節點辨別 flag=0 根 flag=1左子樹 flag=2 右子樹*/

/*因為限于檔案格式隻能先列印"右"子樹,是以flag的用法将是反過來的*/

char HufCod[100]={'/0'};/*用于存儲霍夫曼編碼*/

struct HufNode *Tree_prin(struct HufNode * HufNode,int flag)

{

int offset;

int sh=0;

{/*記錄霍夫曼編碼*/

offset=strlen(HufCod);

if(flag==1)

HufCod[offset]='0';

if(flag==2)

HufCod[offset]='1';

}

while(sh<offset)/*格式列印*/

{

if(HufCod[sh]=='1')

fprintf(wfp,"│ ");

if(HufCod[sh]=='0')

fprintf(wfp," ");

sh++;

}

if(flag==0) /*列印根節點*/

{

fprintf(wfp,"[%c]%-5u/n",HufNode->ID,HufNode->weight);

}

else if(flag==1)/*左葉子列印格式*/

{

fprintf(wfp,"└─[%c]%-5u",HufNode->ID,HufNode->weight);

}

else

{ /*列印右節點*/

fprintf(wfp,"├─[%c]%-5u",HufNode->ID,HufNode->weight);

}

if(flag!=0)/*節點列印霍夫曼編碼*/

{

if(HufNode->ID!='+')

fprintf(wfp,"-->%s/n",HufCod);

else fprintf(wfp,"/n");

}

if(HufNode->rchild!=NULL)

Tree_prin(HufNode->lchild,2); /*先列印右節點*/

if(HufNode->lchild!=NULL)

Tree_prin(HufNode->rchild,1); /*後列印左節點*/

HufCod[offset]='/0';/*撤銷該節點編碼*/

}

int main()

{

struct HufNode *NonceNode =NULL;

if((rfp=fopen("read.txt","r"))==NULL)

{

printf("/n/n/t/tError:not find read.txt!!/n");

getch();exit(1);

}

if((wfp=fopen("Print.txt","w"))==NULL)

{

printf("/n/n/t/tError:not create write.txt!!/n");

getch();exit(1);

}

fprintf(wfp," Huffman Tree Print/n");

fprintf(wfp,"******************************************************/n/n");

NonceNode=CreateHuf(ReadBintree());/*構造霍夫曼樹*/

Tree_prin(NonceNode,0);/*列印霍夫曼樹*/

fclose(rfp);

fclose(wfp);

printf("/n/n/n/t/t/t******************************/n");

printf("/n/t/t/tFrom read.txt readin ....OK/n");

printf("/t/t/tResult to Print.txt ....OK/n");

printf("/n/t/t/t*********** finish ***********");

getch();

return 0;

}

繼續閱讀