17.哈夫曼树类
namespace DSList
{
public class HuffmanTree
{
private HfmCode[] hfmCode;
private HfmNode[] hfmNode;
public HfmCode getHfmCode(int index)
{
return hfmCode[index];
}
public void setHfmCode(int index,HfmCode hfcode)
{
hfmCode[index] = hfcode;
}
public HfmNode getHfmNode(int index)
{
return hfmNode[index];
}
public void setHfmNode(int index, HfmNode hfcode)
{
hfmNode[index] = hfcode;
}
public HuffmanTree(int n)
{
hfmNode = new HfmNode[2 * n - 1];
hfmCode = new HfmCode[n];
}
#region 创建哈夫曼树
//创建哈夫曼树
public void CreateHfmTree(int[] weight, int n)
{
//哈夫曼树hfmNode的初始化
for (int i = 0; i < 2 * n - 1; i++)
{
hfmNode[i] = new HfmNode();
if (i < n)
{
hfmNode[i].Weight = weight[i];
}
else
{
hfmNode[i].Weight = 0;
}
hfmNode[i].Parent = 0;
hfmNode[i].Flag = 0;
hfmNode[i].LChild = -1;
hfmNode[i].RChild = -1;
}
//构造哈曼树的n-1个非叶子结点
for (int i = 0; i < n - 1; i++)
{
int max1, max2, tmp1, tmp2;
max1 = max2 = Int32.MaxValue;
tmp1 = tmp2 = 0;
for (int j = 0; j < n + i; j++)
{
if (hfmNode[j].Weight < max1 && hfmNode[j].Flag == 0)
{
max2 = max1;
tmp2 = tmp1;
tmp1 = j;
max1 = hfmNode[j].Weight;
}
else if (hfmNode[j].Weight < max2 && hfmNode[j].Flag == 0)
{
max2 = hfmNode[j].Weight;
tmp2 = j;
}
}
//找出的两棵权值最小的子树合并为一棵子树
hfmNode[tmp1].Parent = n + i;
hfmNode[tmp2].Parent = n + i;
hfmNode[tmp1].Flag = 1;
hfmNode[tmp2].Flag = 1;
hfmNode[n + i].Weight = hfmNode[tmp1].Weight + hfmNode[tmp2].Weight;
hfmNode[n + i].LChild = tmp1;
hfmNode[n + i].RChild = tmp2;
}
}
#endregion
#region 求哈夫曼编码并输出结果
//求n个叶子结点的哈夫曼编码
public void huffmanCode(int n)
{
HfmCode cd = new HfmCode();
int child, parent;
if (n > 10)
{
Console.WriteLine("n最大值为10,越界!修改hfmCode的bit[n]的大小!");
}
for (int i = 0; i < n; i++)
{
cd.Start = n - 1; //不等长编码的最后一位为n-1
cd.Weight = hfmNode[i].Weight; //取得编码对应权值的字符
child = i;
parent = hfmNode[child].Parent;
hfmCode[i] = new HfmCode();
//由叶子结点向上直到根结点
while (parent != 0)
{
if (hfmNode[parent].LChild == child)
{
cd[cd.Start] = 0; //左孩子结点编码0
}
else
{
cd[cd.Start] = 1; //右孩子结点编码1
}
cd.Start--;
child = parent;
parent = hfmNode[child].Parent;
}
//保存每个结点的编码和不等长编码的起始位
for (int j = cd.Start + 1; j < n; j++)
{
hfmCode[i][j] = cd[j];
hfmCode[i].Start = cd.Start;
hfmCode[i].Weight = cd.Weight; //记住编码对应权值的字符
}
}
//输出结果
for (int i = 0; i < n; i++)
{
Console.Write("Weight=" + hfmCode[i].Weight + " Code=");
for (int j = hfmCode[i].Start + 1; j < n; j++)
{
Console.Write(hfmCode[i][j]);
}
Console.WriteLine();
}
}
#endregion
}
}