霍夫曼树在内存中的存储

#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);
	
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值