哈夫曼树
#include<stdio.h> #include<stdlib.h> #define max 100 struct BTreeNode { char data;//字符信息 int weight;//权重 struct BTreeNode* left; struct BTreeNode* right; }; struct Code//存储每个字符的编码 { int len;//编码长度 char data;//存储字符 int *code;//定义一个可变数组,返回头指针,每一位存储一个编码信息 struct Code *next; }; struct BTreeNode* CreateHuffman(int a[],char p[] ,int n)//创建huffman树,数组a传入权重,数组p传入待编码字符信息,n待编码字符个数 { int i, j; struct BTreeNode **b, *q; b = malloc(n*sizeof(struct BTreeNode)); for (i = 0; i < n; i++) { b[i] = malloc(sizeof(struct BTreeNode)); b[i]->weight=a[i]; b[i]->data=p[i]; b[i]->left = b[i]->right = NULL; } for (i = 1; i < n; i++) { //k1表示森林中具有最小权值的树根结点的下标,k2为次最小的下标 int k1 = -1, k2; for (j = 0; j < n; j++)//让k1初始指向森林中第一棵树,k2指向第二棵 { if (b[j] != NULL && k1 == -1) { k1 = j; continue; } if (b[j] != NULL) { k2 = j; break; } } for (j = k2; j < n; j++)//从当前森林中求出最小权值树和次最小 { if (b[j] != NULL) { if (b[j]->weight < b[k1]->weight) { k2 = k1; k1 = j; } else if (b[j]->weight < b[k2]->weight) k2 = j; } } //由最小权值树和次最小权值树建立一棵新树,q指向树根结点 q = malloc(sizeof(struct BTreeNode)); q->weight = b[k1]->weight + b[k2]->weight; q->data='#'; q->left = b[k1]; q->right = b[k2]; b[k1] = q;//将指向新树的指针赋给b指针数组中k1位置 b[k2] = NULL;//k2位置为空 } free(b); return q; } struct Code* HuffManCoding(struct BTreeNode* FBT, int len)//编码 { static struct Code *head; static int a[10];//静态数组,存储编码信息 if (FBT != NULL) { if (FBT->left == NULL && FBT->right == NULL) { int i; struct Code *p; int *code; p=(struct Code*)malloc(sizeof(struct Code));//申请一个节点 code=(int *)malloc(len*sizeof(int));//申请可变数组,用于存储编码信息 p->data=FBT->data; p->len=len; printf("字母:%c,权值:%d,编码:",FBT->data,FBT->weight); for (i = 0; i < len; i++) { printf("%d",a[i]); code[i]=a[i]; } p->code=code; if (head==NULL)//节点之间的链接 { p->next=NULL; head=p; } else { p->next=head->next; head->next=p; } printf("\n"); } else { a[len] = 0; HuffManCoding(FBT->left, len + 1); a[len] = 1; HuffManCoding(FBT->right, len + 1); } } return head; } void find(struct Code *head,char x)//查找字符x,输出字符编码。head存储编码信息的头指针,x待查找字符 { int i; while (head) { if (head->data==x) { for (i=0;i<head->len;i++) printf("%d",head->code[i]); return ; } else head=head->next; } } int main() { struct Code *head; int n=0,k=0,t=1,i,j,weight[max]={0},isread[max]={0};//weight存储权重 struct BTreeNode* fbt; char S[max],ch,data[max];//S存储字符串,data存储带编码字符 printf("请输入字符串:"); while ((ch=getchar())!='\n') S[n++]=ch; for (i=0;i<n;t=1,i++) { if (isread[i]==1) continue; ch=S[i]; isread[i]=1; for (j=i+1;j<n;j++) { if (ch==S[j]) { isread[j]=1; t++; } } weight[k]=t; data[k++]=ch; } fbt = CreateHuffman(weight,data,k); printf("树中每个叶子结点的哈夫曼编码:\n"); head=HuffManCoding(fbt,0); printf("字符串编码为:"); for (i=0;i<n;i++) { find(head,S[i]); } return 0; }