project-huffmancode

未测试是否正确.......

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#ifndef Huffman        /*define all the function and data structure*/

typedef int ElementType;

typedef struct HeapStruct *HuffHeap;

typedef struct HuffNode *Position;

typedef struct HuffNode *HuffTree;/*define a huffman tree*/

 

HuffHeap Initialize(HuffHeap H,int N);

HuffTree CreateTree(HuffHeap H);

void Insert(struct HuffNode X,HuffHeap H);

Position DeleteMin(HuffHeap H);

void Traversal(HuffTree T);

HuffTree BuildTree(HuffTree HT,int N);

int CheckPrifix(HuffTree HT);

int depth,minsum,stusum,sum;

#endif

 

struct data

{

char c;

int weight;

}Node[200];/*just to save the input data*/

 

struct HeapStruct

{

int Size;

struct HuffNode *Elements;

};/*make a min-heap to save all the elements*/

 

struct HuffNode

{

char data;

int weight;

Position Rchild,Lchild;

};/*define a huffman tree node*/

 

HuffHeap Initialize(HuffHeap H,int N)/*input and get all the element into a min-heap*/

{

int i;

struct HuffNode X;

H=(HuffHeap)malloc(sizeof(struct HeapStruct));/*malloc space for the heap H */

H->Size=0;

H->Elements=(HuffTree)malloc(sizeof(struct HuffNode)*200);

    for(i=1;i<=N;i++)

{

getchar();/*clean the cache memory to avoid wrong input*/

scanf("%c%d",&Node[i].c,&Node[i].weight);

X.data=Node[i].c;X.weight=Node[i].weight;

X.Lchild=X.Rchild=NULL;

Insert(X,H);/*insert the HuffNode X into the min-heap*/

}

return H;

}

 

void Insert(struct HuffNode X,HuffHeap H)/*insert the element into heap H*/

{

int i;

for(i=++H->Size;H->Elements[i/2].weight>X.weight;i/=2)

H->Elements[i]=H->Elements[i/2];/*find the right place*/

H->Elements[i]=X;

}

 

HuffTree DeleteMin(HuffHeap H)

{

int i,child;

Position MinNode=(Position)malloc(sizeof(struct HuffNode));/*malloc another space to save the minnode data*/

struct HuffNode LastNode;

*MinNode=H->Elements[1];/*get the smallest node*/

LastNode=H->Elements[H->Size--];

for(i=1;i*2<=H->Size;i=child)/*percolate down and find the right place to keep the min-heap*/

{

child=i*2;

if(child!=H->Size&&H->Elements[child+1].weight<H->Elements[child].weight)/*find the smaller child*/

child++;

if(LastNode.weight>H->Elements[child].weight)/*when father node's weight is bigger than child node's weight,percolate down*/

H->Elements[i]=H->Elements[child];

else

break;

}

H->Elements[i]=LastNode;/*put the lastnode in the right place*/

return MinNode;

}

 

HuffTree CreateTree(HuffHeap H)/*Create the Huffman Tree*/

{

int N=H->Size,i;

Position X;

for(i=0;i<N-1;i++)/*you need another N-1 node space to create the tree*/

{

X=(Position)malloc(sizeof(struct HuffNode));

/*get the two minimal element from the min-heap and connect them with the new empty node*/

X->Lchild=DeleteMin(H);

X->Rchild=DeleteMin(H);

X->data=' ';/*define every connect node's data as empty ' '*/

X->weight=X->Lchild->weight+X->Rchild->weight;/*the new empty node's weight is equal to the two children's sum weight*/

Insert(*X,H);/*insert the new node back into the min-heap*/

}

return DeleteMin(H);/*return the last node which is the root of the Huffman Tree*/

}

 

void Traversal(HuffTree T)/*prefix traversal and calculate the Huffman Tree's total weight*/

{

if(T){

depth++;/*record the node's depth*/

if(T->Lchild!=NULL)

{

if(T->Lchild->data!=' ')

sum+=T->Lchild->weight*depth;/*find the node and calculate the weight*/

       Traversal(T->Lchild);/*traversal the left child*/

}

if(T->Rchild!=NULL)

{

if(T->Rchild->data!=' ')

sum+=T->Rchild->weight*depth;

Traversal(T->Rchild);/*traversal the right child*/

}

depth--;

}

}

 

HuffTree BuildTree(HuffTree HT,int N)/*according to the code build up the tree*/

{

Position P;

int i=0,len,j;

char s[100],c;

P=HT=(HuffTree)malloc(sizeof(struct HuffNode));/*malloc the root space*/

P->Lchild=P->Rchild=NULL;

P->data=' ';

while(i++<N)

{

P=HT;

getchar();/*clean the chche space*/

scanf("%c",&c);

getchar();

scanf("%s",&s);

len=strlen(s);

/*build up the tree depends on the input code*/

for(j=0;j<len;j++)

{

if(s[j]=='0')/*'0' stand for that the huffman node is in left*/

{/*if have not create the node then make it*/

if(P->Lchild==NULL){

P->Lchild=(HuffTree)malloc(sizeof(struct HuffNode));

P->Lchild->Lchild=P->Lchild->Rchild=NULL;

}

P=P->Lchild;

}

else

if(s[j]=='1')

{

if(P->Rchild==NULL){

P->Rchild=(HuffTree)malloc(sizeof(struct HuffNode));

P->Rchild->Lchild=P->Rchild->Rchild=NULL;

}

P=P->Rchild;

}

if(j!=len-1)/*it it is a two-degree node then make its data ' '*/

P->data=' ';

else

{/*save the data in the leaf node*/

P->data=c;

   P->weight=Node[i].weight;

   P->Lchild=P->Rchild=NULL;

}

}

}

return HT;/*return back the root*/

}

 

int CheckPrifix(HuffTree HT)/*check the new tree wether is a huffman tree*/

{

if(HT)

{

if((HT->data!=' '&&(HT->Lchild!=NULL||HT->Rchild!=NULL))||(HT->data==' '&&(HT->Lchild==NULL||HT->Rchild==NULL)))

return 0;/*check the current node wether meet the huffman cintrains*/

if(HT->data!=' '&&(HT->Lchild==NULL&&HT->Rchild==NULL))

return 1;

return (CheckPrifix(HT->Lchild)&&CheckPrifix(HT->Rchild));/*check the children nodes*/

}

}

 

int main()

{

HuffHeap H=NULL;

HuffTree T=NULL,HT=NULL;

int N,M,i,times=0;

scanf("%d",&N);

while(N!=0)

{

times++;

H=Initialize(H,N);/*Initialize the Heap*/

T=CreateTree(H);/*create the huffmantree according to the heap H*/

depth=sum=0;

   Traversal(T);/*get the huffman tree's total weight*/

minsum=sum;

scanf("%d",&M);

printf("Case %d:\n",times);

for(i=0;i<M;i++)

{

HT=BuildTree(HT,N);/*build the tree based on the input code*/

depth=sum=0;

       Traversal(HT);/*get the new tree's total weight*/

stusum=sum;

if(stusum==minsum&&CheckPrifix(HT))/*check the new tree wether meet the huffman tree's two contrains*/

printf("Yes\n");

else

printf("No\n");

}

   scanf("%d",&N);/*next set*/

}

return 0;

}

posted @ 2011-01-11 15:20  楚夕  阅读(266)  评论(0编辑  收藏  举报