#include <stdio.h>
#include <stdlib.h>
/*思路:首先霍夫曼树在内存中存储包括四个部分:权值:weght,双亲:,左孩子,右孩子还要知道霍夫曼树的思想是权值大的路径短
*所以我们可以选取这里面权值最小的两个构成一对叶子结点,在以此类推就可以构建一个霍夫曼树
*我们通过观察霍夫曼树可以发现该树只有度为0的和度为2的两种,所以假设有n个叶子结点的霍夫曼树,则需要开辟多大的空间:n0 = n2 + 1,n = no + n2,n = n0 + n0 - 1;
*还有就是找到最小的值,我的思路是把它们的权值存在一个数组中但前提是它们的双亲为0,然后用选择排序,再和它们的权值和排序得到的最小值和最倒数第二小值比较,并用两个变量来记录它们的位置然后我们就可以来创建霍夫曼树
*/
typedef struct HuffmanNode{
int weght;//权值
int parent,lch,rch;
}HuffmanNode, *HuffmanTree;
//找到权值最小的两个结点的位置
void Select(HuffmanTree HT,int i,int &s1,int &s2)
{
int a[i];
int j,k = 0,x,y,temp;
for(j = 1;j <= i;j ++)
{
//printf("%d\t",HT[j].parent);
if(HT[j].parent == 0)
{
a[k ++] = HT[j].weght;
}
}
printf("排序前:\n");
for(x = 0;x < k;x ++)
{
printf("%d\t",a[x]);
}
printf("\n");
for(j = 0;j < k - 1;j ++)
{
y = j;
for(x = j + 1;x < k;x ++)
{
if(a[y] > a[x])
{
y = x;
}
}
if(y != j)
{
temp = a[y];
a[y] = a[j];
a[j] = temp;
}
}
for(x = 0;x < k;x ++)
{
printf("%d\t",a[x]);
}
printf("\n");
for(x = 1;x <= i;x ++)
{
if(HT[x].parent == 0)
{
if(a[0] == HT[x].weght)
{
s1 = x;
}
// if(a[0] == 29 && a[1] == 29)
// {
// printf("s1 = %d\t s2 = %d\n",s1,s2);
// }
}
}
for(x = 1;x <= i;x ++)
{
if(HT[x].parent == 0)
{
if(a[1] == HT[x].weght && x != s1)
{
s2 = x;
}
}
}
}
void CreatHuffmanTree(HuffmanTree HT,int n)
{
int m,i;
int s1,s2;
if(n <= 1)
{
return;
}
m = 2 * n - 1;
HT = (HuffmanTree) malloc(sizeof(HuffmanNode) * (m + 1));
for(i = 1;i <= m;i ++)
{
HT[i].lch = 0;
HT[i].parent = 0;
HT[i].rch = 0;
}
printf("请输入权值:\n");
for(i = 1;i <= n;i ++)
{
scanf("%d",&HT[i].weght);
}
for(i = n + 1;i <= m;i ++)
{
Select(HT,i - 1,s1,s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lch = s1;
HT[i].rch = s2;
HT[i].weght = HT[s1].weght + HT[s2].weght;
//printf("左孩子\t双亲\t右孩子\t权值\n");
// printf("%d\t%d\t%d\t%d\n",HT[i].lch,HT[i].parent,HT[i].rch,HT[i].weght);
//printf("s1 = %d\ts2 = %d\n",s1,s2);
}
printf("左孩子\t双亲\t右孩子\t权值\n");
for(i = 1;i <= m;i ++)
{
printf("%d\t%d\t%d\t%d\n",HT[i].lch,HT[i].parent,HT[i].rch,HT[i].weght);
}
}
void Display(HuffmanTree HT,int n)
{
int i;
int m = 2 * n - 1;
printf("左孩子\t双亲\t右孩子\t权值\n");
for(i = 1;i <= m;i ++)
{
printf("%d\t%d\t%d\t%d\t",HT[i].lch,HT[i].parent,HT[i].rch,HT[i].weght);
}
}
//
int main()
{
HuffmanTree HT;
int n;
printf("请输入叶子结点数:");
scanf("%d",&n);
CreatHuffmanTree(HT,n);
//Display(HT,n);
}
霍夫曼树在内存中的存储
最新推荐文章于 2023-05-14 17:43:26 发布