实现效果:
输入 树的结点 以及各个结点的权值
输出 将赫夫曼编码输出
输入
4
A 10
B 20
C 15
D 17
输出
A:00
B:11
C:01
D:10
思路:
第一步:将所有结点的元素,以及所带权值放到一个数组arr里面。这个数组arr的一行包括结点元素,结点权值,结点的双亲,结点的左孩子,结点的右孩子。并将所知结点的的双亲、左孩子,右孩子赋值为-1。
比如实例中有4个结点 啧这四个节点在数组中的值如下
A 10 -1 -1 -1
B 20 -1 -1 -1
C 15 -1 -1 -1
D 17 -1 -1 -1
第二步:通过findMin()函数知道已知所有结点中的最小两个权值的下标,将它们的权值赋给新增的结点(野史他们的双亲)。
(
A 10 -1 -1 -1
B 20 -1 -1 -1
C 15 -1 -1 -1
D 17 -1 -1 -1
25(10+15) -1 0(A的下标) 2(C的下标) --(这边注意了那个由于结点的元素是未知的所以这边没给结点但元素赋值
)
第三步:反复执行findMin()函数直到到达根节点
第四步:从第一个数组坐标开始,反复寻找其双亲节点,若是双亲节点的左孩子保存0右孩子保存1(这边默认权值较小的为左孩子,否则为右孩子)
第五步:将结点与赫夫曼编码输出
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define INF 1000
#define MAX 50
/*
4
A 10
B 20
C 15
D 17
*/
typedef int Status;
typedef char** HuffmanCode;
typedef struct HuffmanNode{
char data;
int weight;
int parent,lchild,rchild;
}HuffmanNode;
typedef struct HuffmanTree{
HuffmanNode arr[MAX];
int n;
}HuffmanTree;
Status initTree(HuffmanTree *T){
int i=0;
scanf("%d",&T->n);
for(i = 0; i < T->n; i++){
fflush(stdin);
scanf("%c%d",&T->arr[i].data,&T->arr[i].weight);
T->arr[i].parent=T->arr[i].lchild=T->arr[i].rchild=-1;
}
return OK;
}
Status findMin(HuffmanTree T,int *m1,int *m2,int num){
int i,min1=INF,min2=INF;
for(i = 0; i < num; i++){
if(T.arr[i].parent==-1){
if(T.arr[i].weight < min1){
min2 = min1;*m2 = *m1;
min1 = T.arr[i].weight;*m1 = i;
}else if(T.arr[i].weight < min2){
min2 = T.arr[i].weight;*m2 = i;
}
}
}
printf("AAA:%d-->%d\t%d-->%d\n",min1,*m1,min2,*m2);
if(min1 == INF || min2 == INF) return ERROR;
else return OK;
}
Status createTree(HuffmanTree *T){
int m1 = 0;
int m2 = 0;
int i=T->n;
while(findMin((*T),&m1,&m2,i)){
T->arr[m1].parent = T->arr[m2].parent = i;
T->arr[i].weight = T->arr[m1].weight + T->arr[m2].weight;
T->arr[i].lchild = m1;
T->arr[i].rchild = m2;
T->arr[i].parent = -1;
i++;
}
return OK;
}
void show(HuffmanTree T){
int i;
for(i = 0; i < T.n+3; i++){
printf("%c %d\t%d %d %d\n ",T.arr[i].data,T.arr[i].weight,T.arr[i].parent,T.arr[i].lchild,T.arr[i].rchild);
T.arr[i].parent=T.arr[i].lchild=T.arr[i].rchild=-1;
}
}
void createHuffmanCode(HuffmanTree T, HuffmanCode *HC){
int i,c,p,top,j;
char s[MAX];
(*HC) = (char**)malloc(sizeof(char *)*T.n);
for(i = 0;i<T.n;i++){
top = 0;
c = i;
p = T.arr[i].parent;
while(p != -1){
if(T.arr[p].lchild == c) s[top++] = '0';
else s[top++] = '1';
c = p; p = T.arr[p].parent;
}
(*HC)[i] = (char *)malloc(sizeof(char)*5);
j = 0;
(*HC)[i][j++] = T.arr[i].data;
(*HC)[i][j++] = ':';
while(top != 0){
(*HC)[i][j++] = s[--top];
}
(*HC)[i][j] = '\0';
}
}
int main()
{
HuffmanTree T;
HuffmanCode g;
int i;
initTree(&T);
createTree(&T);
createHuffmanCode(T,&g);
for(i = 0;i<T.n;i++){
printf("%s\n",g[i]);
}
return 0;
}