終於完成了初版的鏈表版 哈弗曼編碼
效果如下
/*************************************************************************
> File Name: huff.c
> Author:劉嘉輝
> Mail:
> Created Time: 2017年11月20日 星期一 21時11分48秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
typedef struct node {
char a;
int weight;
struct node *left;
struct node *right;
}Htree;
typedef struct ch{
char c;
int *pp;
}Node;
//創建哈弗曼樹
Htree * create_tree(int A[] ,int n)
{
Htree *q;
Htree **B; //存放葉子節點的數組
int min=-1,next_min;
//將數據存儲在空間裏
int i ,j;
B = (Htree **) malloc(n*sizeof(Htree *));
for ( i=0 ;i<n;i++){
B[i] = (Htree *)malloc(sizeof(Htree) ) ;
B[i]->weight = A[i];
B[i]->left = B[i]->right = NULL;
}
//循環n-1次進行建立哈弗曼樹
for(i=1; i<n ; i++){
min=-1;
// next_min;
//對最小 次小進行初始化
for(j=0;j<n;j++){
if(B[j]!= NULL && min == -1 ) //特別要注意條件的設置
{
min = j;
continue;
}
if(B[j]!=NULL)
{
next_min = j;
break;
}
}
//遍歷整個數組找出最小和次最小 以下有兩種方式
/*
int temp;
if (B[min]->weight > B[next_min]->weight) {
temp=min;min=next_min;next_min=temp;
}
//printf("min=%d next_min=%d\n",min,next_min );
for(j=0;j<n;j++)
{
if(B[j] != NULL ){
if( B[j]->weight < B[min]->weight )
{
next_min=min;
min=j;
} else if (B[j]->weight<B[next_min]->weight && j!=min) {
next_min=j;
}
}
}
*/
for (j = next_min ; j<n; j++)
{
if(B[j] != NULL )
{
if(B[j]->weight < B[min]->weight )
{
next_min = min;
min = j; //首次時相當於min和 next_min發生了交換 非常精簡
}
else if(B[j]->weight < B[next_min]->weight )
next_min = j;
}
}
//生成新節點進行賦值
q = (Htree *) malloc (sizeof(Htree));
q->weight = B[min]->weight + B[next_min]->weight;
q->left = B[min];
q->right = B[next_min];
B[min] = q;
B[next_min] = NULL;
for(int k =0;k<n;k++)
{
if(B[k])
printf("%d ",B[k]->weight);
else
printf("NULL ");
}
printf("\n");
}
free(B);
return q;
}
void visit_Htree(Htree *TT)
{
if(TT != NULL)
{
printf("%d ",TT->weight );
visit_Htree(TT->left);
visit_Htree(TT->right);
}
}
//哈弗曼編碼
void Huffmancoding(Htree *TT,int len)
{
static int code[10];
if(TT != NULL)
{
if(TT->left == NULL && TT->right ==NULL)
{
printf("%d 處的哈弗曼編碼爲:",TT->weight);
int j=0;
for ( j= 0;j<len;j++)
printf("%d", code[j]);
printf("\n");
}
else //進入節點之後 進左右之前分別存儲0或1
{
code[len] = 0;
Huffmancoding(TT->left, len+1);
code[len] = 1;
Huffmancoding(TT->right, len+1);
}
}
}
int main ()
{
Htree *TT;
//申請存放權值的空間
int *A;
int n;
while (1){
scanf("%d",&n);
if(n > 1)
break;
}
A = (int *) malloc(sizeof(int) * n);
for (int i=0; i<n ; i++){
scanf("%d",& A[i]);
}
//創建哈弗曼樹 還需加一條字符數組進行辨認
TT = create_tree(A,n);
visit_Htree(TT);
printf("\n");
//哈弗曼編碼
Huffmancoding(TT,0);
}