huffman 树

void CreateHT(HTNode ht[], int n)
{
	for (int k = 0; k < 2*n - 1; ++k)
	{
		ht[k].parent = -1;
		ht[k].lchild = -1;
		ht[k].rchild = -1;
	}
	for (int i = n; i <= 2*n - 1; ++i)
	{
		double lWight = 32767, rWight = 32767;
		int lNode = -1, rNode = -1;

		for (int j = 0; j < i - 1; ++j)
		{
			if (ht[j].parent == -1)
			{
				if (ht[j] < lWight)
				{
					rWight = lWight;
					rNode = lNode;

					lWight = ht[j];
					lNode = j;
				}
				else if (ht[j] < rWight)
				{
					rWight = ht[j];
					rNode = j;
				}
			}
		}

		ht[lNode].parent = i;
		ht[rNode].parent = i;

		ht[n].weight = lWight + rWight;
		ht[n].lchild = lNode;
		ht[n].rchild = rNode;
	}
}//127
//根据哈夫曼树求对应的哈夫曼编码的算法如下:
typedef struct 
{
	char cd[N];
	int  start;
} HCode;

void CreateHCode(HTNode ht[],HCode hcd[],int n)
{	
	int i,f,c; HCode hc;

	for (i=0;i<n;i++)		/*根据哈夫曼树求哈夫曼编码*/
	{   
		hc.start=n;
		c=i; 
		f=ht[i].parent;

		while (f!=-1)   /*循环直到无双亲结点即到达树根结点*/
		{    
			if (ht[f].lchild==c)	/*当前结点是左孩子结点*/
			hc.cd[hc.start--]='0';
			else	  /*当前结点是双亲结点的右孩子结点*/
			hc.cd[hc.start--]='1';
			c=f;f=ht[f].parent; /*再对双亲结点进行同样的操作*/
		}
		
		hc.start++;/*start指向哈夫曼编码最开始字符*/
		hcd[i]=hc;
	}
} 
// S = {S1, S2, ... , Sk} x

// MAKE_SET(x)  UNION(x,y)  FIND_SET(x)
typedef struct node
{   
	int data;		/*结点对应人的编号*/
	int rank;		/*结点对应秩*/

	int parent;		/*结点对应双亲下标*/
} UFSTree;		/*并查集树的结点类型*/

void MAKE_SET(UFSTree t[])	/*初始化并查集树*/
{ 
	int i;
	
	for (i=1;i<=N;i++)
	{   
		t[i].data=i;		/*数据为该人的编号*/
		t[i].rank=0;		/*秩初始化为0*/
		t[i].parent=i;		/*双亲初始化指向自已*/
	}
} 

int FIND_SET(UFSTree t[],int x)	/*在x所在子树中查找集合编号*/
{
	if (x!=t[x].parent)	/*双亲不是自已*/
		return(FIND_SET(t,t[x].parent));/*递归在双亲中找x*/
	else
		return(x);		/*双亲是自已,返回x*/
} 
//时间复杂度为O(log2n) 
void UNION(UFSTree t[],int x,int y)/*将x和y所在的子树合并*/
{ 
	x=FIND_SET(t,x);	/*查找x所在分离集合树的编号*/
	y=FIND_SET(t,y);	/*查找y所在分离集合树的编号*/
	if (t[x].rank>t[y].rank)/*y结点的秩小于x结点的秩*/
		t[y].parent=x;  /*将y连到x结点上,x作为y的孩子结点*/
	else				/*y结点的秩大于等于x结点的秩*/
	{    
		t[x].parent=y;	 /*将x连到y结点上,y作为x的孩子结点*/
		if (t[x].rank==t[y].rank)	/*x和y结点的秩相同*/
		t[y].rank++;		/*y结点的秩增1*/
	}
}
//对于n个人,本算法的时间




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值