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个人,本算法的时间