一直被数据结构中的huffman树困扰,理论都知道可是一到写代码就犯浑,最近突然灵感大发,把之前一直困扰我的问题,给解决了,现在把代码分享出来。
/*
************************************************
*Name : Huffman Code *
*Date : 2014-12-16 *
*Author : marksman *
*Aim : Create a Huffman tree and get the huff- *
* -man Code *
************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100
/*
*huffman tree structure
*/
typedef struct
{
int weight;
int parent,leftchild,rightchild;
}*huffman_tree,huffman;
typedef char** huffman_code;
/*
*Sort the frequency
*/
int * sort(int a[],int n)
{
int i,j;
for(j=0;j<n-1;j++)
{
for(i=0;i<n;i++)
{
if(a[i]>a[i+1])
{
int temp=0;
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
}
return a;
}
/*
*Init the structure
*/
huffman_tree init_huffman_tree(huffman_tree tree)
{
tree = (huffman*)malloc(sizeof(huffman));
return tree;
}
/*
*Delete a[0],a[1] and narrow the array
*/
int * decade_member(int a[],int n,int m)
{
int i;
int *b;
int j=0;
b=(int*)malloc(sizeof(int)*(n-1));
memset(b,0,sizeof(int)*(n-1));
/*
*delete a[0]
*/
a[1]=m;
for(i=1;i<n;i++)
{
b[j++]=a[i];
}
return b;
}
/*
*select the two minimal numbers and find it in huffman tables
*/
int * select(huffman_tree tree,int m,int a,int b)
{
int *min;
int i;
min = (int *)malloc(sizeof(int)*2);
memset(min,-1,sizeof(min)*2);
for(i=0;i<m;i++)
{
if(tree[i].weight==a)
min[0]=i;
if(tree[i].weight==b)
min[1]=i;
}
return min;
}
/*
*Create the huffman table
*/
huffman_tree create_tree(huffman_tree tree,int a[],int n)
{
int i;
int m; //store all leaves ,size is m
int j=0;
int *b;
int length=n;
m=2*n-1;
/*
*Init the table of huffman
*/
for(i=0;i<m;i++)
{
if(i<n)
tree[i].weight=a[i];
else
tree[i].weight=-1;
tree[i].parent=-1;
tree[i].leftchild=-1;
tree[i].rightchild=-1;
}
b=(int *)malloc(sizeof(int)*(n-j));
memset(b,0,sizeof(int)*(n-j));
memcpy(b,a,sizeof(int)*(n-j));
for(i=n;i<m;i++)
{
int *min;
int c=0;
tree[i].weight=b[0]+b[1];
min=select(tree,m,b[0],b[1]);
tree[i].leftchild=min[0];
tree[i].rightchild=min[1];
tree[min[0]].parent=i;
tree[min[1]].parent=i;
c=b[0]+b[1];
b=decade_member(b,length,c);
length-=1;
b=sort(b,length);
}
}
/*
*Create the huffman code
*/
char** create_huffman_Code(huffman_tree tree,int n)
{
huffman_code code;
int i=0;
char *cd;
int c=0;
int f=0;
code = (huffman_code)malloc(sizeof(char *)*(n+1));
cd = (char *)malloc(sizeof(char)*n);
memset(cd,'\0',sizeof(char)*n);
/*
*backward visit the leaves to root
*/
for(i=0;i<n;i++)
{
int temp=n-1;
for(c=i,f=tree[i].parent;f!=-1;c=f,f=tree[f].parent)
{
if(tree[f].leftchild==c)
cd[--temp]='0';
else
cd[--temp]='1';
}
code[i]=(char *)malloc(sizeof(char)*(n-temp));
memset(code[i],'\0',sizeof(char)*n);
strcpy(code[i],&cd[temp]);
}
free(cd);
return code;
}
/*
*Output the huffman tree table
*/
void output_huffman_tree(huffman_tree tree,int m)
{
int i=0;
for(i=0;i<m;i++)
printf("No.%d ** weight = %d ** parent = %d ** leftchild = %d ** rightchild = %d\n", \
i,tree[i].weight,tree[i].parent,tree[i].leftchild,tree[i].rightchild);
}
/*
*output the huffman code
*/
void output_huffman_code(huffman_code code,int n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("%c huffman_code is : %s\n",'A'+i,code[i]);
}
}
int main()
{
int n,i;
int *a;
huffman tree[N];
int m;
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
memset(a,0,n*sizeof(a));
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
a=sort(a,n);
create_tree(tree,a,n);
m=2*n-1;
/*
*print the table
*/
output_huffman_tree(tree,m);
huffman_code code;
code=create_huffman_Code(tree,n);
output_huffman_code(code,n);
return 0;
}