#include<stdio.h>
#include<stdlib.h>
#include<String.h>
#define MAXLEN 100
#define MAX 100;
typedef struct node {
int weight;
int lchild;
int rchild;
int parent;
char info;//每个节点的信息
}hfNode;
/*
typedef double vector[100];
vector arr; ====> 等价于 double arr[100];
*/
typedef hfNode hfm[MAXLEN];
int n;
/*初始化*/
void InitHfm(hfm hf) {
int i;
printf("输入n的值:");
scanf("%d", &n);
getchar();
for(i=0; i<n; i++) {
hf[i].weight = 0;
hf[i].lchild = -1;
hf[i].rchild = -1;
hf[i].parent = -1;
}
printf("\n");
}
/*输入权值*/
void InputWeight(hfm hf) {
int w, i;
char inf;//
for(i=0; i<n; i++) {
printf("请输入第%d个字符:", i+1);
scanf("%c", &inf);
getchar();
hf[i].info = inf;
printf("请输入第%d个字符的权值:", i+1);
scanf("%d", &w);
getchar();
hf[i].weight = w;
printf("\n");
}
}
/*找到两个权值最小的字符*/
void SelectMin(hfm hf, int i, int &p1, int &p2) {
long min1 = MAX;
long min2 = MAX;
int j;
for(j=0; j<i; j++) {//最小
if(hf[j].parent == -1) {
if(min1>hf[j].weight) {
min1 = hf[j].weight;
p1 = j;
}
}
}
for(j=0; j<i; j++) {//次小
if(hf[j].parent == -1) {
if(min2>hf[j].weight && j!=p1) {
min2 = hf[j].weight;
p2 = j;
}
}
}
}
/*创建哈夫曼树*/
void CreatHfm(hfm hf) {
int i, p1, p2;
InitHfm(hf);
InputWeight(hf);
for(i=n; i<2*n-1; i++) {
SelectMin(hf, i, p1, p2);//找出两个权值最小的p1,p2
hf[p1].parent = i;//parent是编号
hf[p2].parent = i;
hf[i].lchild = p1;
hf[i].rchild = p2;
hf[i].weight = hf[p1].weight + hf[p2].weight;
hf[i].info = '0';
hf[i].parent = -1;
}
}
/*输出哈夫曼树*/
void PrintHfm(hfm hf) {
int i;
printf("\t\t权重\t父母\t左孩子\t右孩子\t字符\t\n");
for(i=0; i<2*n-1; i++) {
printf("\t\t%d\t%d\t%d\t%d\t%c\n", hf[i].weight, hf[i].parent,
hf[i].lchild, hf[i].rchild, hf[i].info);
}
printf("\n\n");
}
/*哈夫曼树路径递归算法*/
void HfmPath(hfm hf, int i, int j) {
int a, b;
a = i;
b = j = hf[i].parent;
if(hf[b].parent != -1) {
i = j;
HfmPath(hf, i, j);
}
if(hf[b].lchild == a)
printf("0");
else
printf("1");
}
/*对字符进行初始编码*/
void HfmNode(hfm hf) {
int i, j;
for(i=0; i<n; i++) {
j = 0;
printf("\t\t%c\t%d\t", hf[i].info, hf[i].weight);
HfmPath(hf, i, j);
printf("\n");
}
}
/*对用户输入的电文进行编码*/
void EnCode(hfm hf) {
char data[1000];
int i, j;
printf("\n\n请输入你要编码的字符:");
gets(data);
printf("编码结果为:");
for(j=0; data[j]!='\0'; j++) {
for(i=0; i<n; i++) {
if(data[j]==hf[i].info)
HfmPath(hf, i, j);
}
}
}
/*对用户输入的密文进行译码*/
void DeCode(hfm hf) {
char data[100];
int i, j, len;
j = 2*n - 2;//j初始从树的根节点开始
printf("\n\n请输入需要译码的字符串:");
scanf("%s", data);
len = strlen(data);
printf("译码的结果为:");
for(i=0; i<len; i++) {
/*遇到0结束,然后j指向根节点,
每次需从根节点找下来*/
if(data[i] == '0') {
j = hf[j].lchild;
if(hf[j].lchild == -1) {
printf("%c", hf[j].info);
j = 2*n - 2;
}
}
else if(data[i] == '1') {
j = hf[j].rchild;
/*当全为1时会执行下面的if*/
if(hf[j].rchild == -1) {
printf("%c", hf[j].info);
j = 2*n - 2;
}
}
}
printf("\n");
}
main() {
int i, j;
hfm hf;
CreatHfm(hf);
PrintHfm(hf);
HfmNode(hf);
EnCode(hf);
DeCode(hf);
}
哈夫曼编码
最新推荐文章于 2021-05-18 02:00:19 发布