写了我1个小时wok
哈夫曼树的构建先要找两个最小的两个数
int* minxx(struct HFtree* HF)
{
int min = 99999;
int minindex=-1;
int mintwoindex = -1;
int* res = (int*)malloc(sizeof(int) * 2);
for (int i = 0; i < HF->len; i++)
{
if (HF->data[i].dad == 0)
{
if (HF->data[i].val < min)
{
min = HF->data[i].val;
minindex = i;
}
}
res[0] = minindex;
}
min = 99999;
for (int i = 0; i < HF->len; i++)
{
if (HF->data[i].dad == 0&&i!=minindex)
{
if (HF->data[i].val < min)
{
min = HF->data[i].val;
mintwoindex = i;
}
}
res[1] = mintwoindex;
}
return res;
}
然后就是这个树的初始化,我们先要让他的父节点都是0,左右子节点都是-1
struct HFtree* start(int len,int* a)
{
struct HFtree* HF = (struct HFtree*)malloc(sizeof(struct HFtree));
HF->data = (Node*)malloc(sizeof(Node) * (2 * len - 1));
HF->len = len;
for (int i = 0; i < len; i++)
{
HF->data[i].val = a[i];
HF->data[i].left = -1;
HF->data[i].right = -1;
HF->data[i].dad = 0;
}
return HF;
}
然后就是他的树的建立
void creat(struct HFtree* HF)
{
int* res;
int len = HF->len * 2 - 1;
for (int i = HF->len; i < len; i++)
{
res = minxx(HF);
HF->data[i].dad = 0;
HF->data[i].val = HF->data[res[0]].val + HF->data[res[1]].val;//父亲的价值为儿子的价值加一起
HF->data[i].left = res[0];//左儿子为下标
HF->data[i].right = res[1];
HF->data[res[0]].dad = i;//左右儿子的父亲为i
HF->data[res[1]].dad = i;
HF->len++;//创建出一个就加1
}
}
先序遍历,如果有左右儿子就一直找
void xianxu(struct HFtree* HF,int index)//先序遍历哈夫曼树
{
if (index != -1)
{
printf("%d ", HF->data[index].val);
xianxu(HF, HF->data[index].left);
xianxu(HF, HF->data[index].right);
}
}
总的代码就是
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int val;//该点的价值
int left, right;//左右节点
int dad;//父亲节点
}Node;
struct HFtree
{
Node* data;//数组
int len;//数组长度
};
struct HFtree* start(int len,int* a)
{
struct HFtree* HF = (struct HFtree*)malloc(sizeof(struct HFtree));
HF->data = (Node*)malloc(sizeof(Node) * (2 * len - 1));
HF->len = len;
for (int i = 0; i < len; i++)
{
HF->data[i].val = a[i];
HF->data[i].left = -1;
HF->data[i].right = -1;
HF->data[i].dad = 0;
}
return HF;
}
int* minxx(struct HFtree* HF)
{
int min = 99999;
int minindex=-1;
int mintwoindex = -1;
int* res = (int*)malloc(sizeof(int) * 2);
for (int i = 0; i < HF->len; i++)
{
if (HF->data[i].dad == 0)
{
if (HF->data[i].val < min)
{
min = HF->data[i].val;
minindex = i;
}
}
res[0] = minindex;
}
min = 99999;
for (int i = 0; i < HF->len; i++)
{
if (HF->data[i].dad == 0&&i!=minindex)
{
if (HF->data[i].val < min)
{
min = HF->data[i].val;
mintwoindex = i;
}
}
res[1] = mintwoindex;
}
return res;
}
void creat(struct HFtree* HF)
{
int* res;
int len = HF->len * 2 - 1;
for (int i = HF->len; i < len; i++)
{
res = minxx(HF);
HF->data[i].dad = 0;
HF->data[i].val = HF->data[res[0]].val + HF->data[res[1]].val;//父亲的价值为儿子的价值加一起
HF->data[i].left = res[0];//左儿子为下标
HF->data[i].right = res[1];
HF->data[res[0]].dad = i;//左右儿子的父亲为i
HF->data[res[1]].dad = i;
HF->len++;//创建出一个就加1
}
}
void xianxu(struct HFtree* HF,int index)//先序遍历哈夫曼树
{
if (index != -1)
{
printf("%d ", HF->data[index].val);
xianxu(HF, HF->data[index].left);
xianxu(HF, HF->data[index].right);
}
}
int main()
{
int a[4] = { 1,2,3,4 };
struct HFtree* HF;
HF = start(4, a);
creat(HF);//建树也没错
for (int i = 0; i < 2 * 4 - 1; i++)
{
printf("%d ", HF->data[i].val);
printf("%d ", HF->data[i].left);
printf("%d ", HF->data[i].right);
printf("%d ", HF->data[i].dad);
printf("\n");
}
//printf("%d ", HF->data[4 * 2 - 1].left);
xianxu(HF, HF->len - 1);//最后的一个数为根
//int* res = minxx(HF);
//printf("%d %d", res[0], res[1]);
}
还有个哈夫曼树的编码没有搞出来,和二叉树的遍历感觉差不多,只不过向左就是输出0,向右就是输出1,明天在搞
下班下班