#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct huffman {
int weight;
int parent, lchild, rchild;//parent放双亲再数组中的下标
}Hufnode,*HufTree;
typedef char** HuffmanCode;//动态二维数组,可看作若干个一维数组组成
void Creat_Huffmancode(HufTree HT, HuffmanCode * HC, int n)//寻找字符对应的编码,我们从叶子结点出发
//一直到根结点
{
*HC = (HuffmanCode)malloc((n + 1) * sizeof(char*));
char* ch = (char*)malloc(n * sizeof(char));//森林有n个根结点,临时数组ch就需要n个空间
//(实际是n-1,但最后一个存放'\0')
ch[n - 1] = '\0';
for (int i = 1; i <= n; i++)//n个森林中的根结点存放在哈夫曼树数组中的1-n中
{
int start = n - 1;
int c = i;
int f = HT[i].parent;
while (f != 0)
{
start--;
if (HT[f].lchild = c)
ch[start] = 0;
else
ch[start] = 1;
c = f;
f = HT[f].parent;
}
(*HC)[i] = (char*)malloc((n - start) * sizeof(char));
strcpy((*HC)[i], &ch[start]);//将临时数组中不为0的第一个元素开始复制到
}
}
void select(HufTree HT, int i, int& s1, int& s2)//&是传址调用,会将形参中s1的值返回给实参
{
int min = 1;
for (int n = 2; n <= i; n++)
{
if (HT[n].parent==0)//双亲是0表示是森林中的根结点
{
if ( HT[min].weight> HT[n].weight)//选取权最小的元素的下标
min = n;
}
}
s1 = min;
min = 1;
for (int n = 2; n <= i; n++)
{
if (HT[n].parent==0&&n!=s1)//不能是权第一小元素的下标
{
if (HT[min].weight > HT[n].weight)
min = n;
}
}
s2 = min;
}
HufTree Creat_HuffmanTree(int n)
{
int x;
int m = 2 * n-1;
HufTree HT;//定义一个指针,指针就相当于数组,把指针看作数组
HT = (HufTree)malloc((m+1)*sizeof(Hufnode));//给数组开辟空间,数组中要放m+1个元素
//初始化
for (int i = 1; i <= m; i++)//从下标为1到m
{
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for (int i = 1; i <= n; i++)
{
scanf_s("%d", &x);
HT[i].weight = x;
}
int s1, s2;
for (int i = n - 1; i <= m; i++)
{
select(HT, i-1,s1,s2);//选用两小造新树
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
}
return HT;
}
void Unite_Huffmancode(HufTree HT, int code[],int num,int n)//解码
{
int p=n;
for (int i = 0; i < num; i++)
{
while (HT[p].lchild != 0)
{
if (code[i] = 0)
p = HT[p].lchild;
else
p = HT[p].rchild;
}
printf("%d ", HT[p].weight);
p = n;
}
}
int main()
{
HufTree HT = Creat_HuffmanTree(3);
return 0;
}