该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
void CHuffmanTree(HuffNode HuffTreeNode[])
{
for (int i = 0; i<512; i++)
{
if (HuffTreeNode[i].count != 0)//前面已把256种颜色出现的频率计算
{
HuffTreeNode[i].b = (unsigned char)i;//如果有权值,设置叶子结点的字节(符)
}
else
{
HuffTreeNode[i].b = 0;//如果没有权值,表示该字符没有在图片中使用
}
//对结点进行初始化,所有结点的父结点都不存在,左右孩子都不存在
HuffTreeNode[i].parent = -1;
HuffTreeNode[i].lch = -1;
HuffTreeNode[i].rch = -1;
}
}
//Huffman树排序
void Pass(HuffNode HuffTreeNode[])
{
int j;
HuffNode tmp;
for (int i = 0; i<256; i++)
{
for (j = i + 1; j<256; j++)
{
if (HuffTreeNode[i].count
{
tmp = HuffTreeNode[j];
HuffTreeNode[j] = HuffTreeNode[i];
HuffTreeNode[i] = tmp;
}
}
}
printf("字节下标\t字节值\t权值\t父亲\t左孩子\t右孩子\t\n");
for (int k = 0; k<256; k++)
{
if (HuffTreeNode[k].count != 0)
printf("%d\t\t%02x\t%d\t%d\t%d\t%d\n", k, HuffTreeNode[k].b, HuffTreeNode[k].count, HuffTreeNode[k].parent, HuffTreeNode[k].lch, HuffTreeNode[k].rch);
}
}
//生成Huffman树
int SHuffmanTree(HuffNode HuffTreeNode[])
{
int i, j;
for (i = 0; i<256; i++)
if (HuffTreeNode[i].count == 0)
break;
int n = i;
int m = 2 * n - 1;
long min1, pt1;
for (i = n; i
{
min1 = 0x7FFFFFFF;//预设的最大权值,即结点出现的最大次数
for (j = 0; j
{
//parent!=-1 说明该结点已在哈夫曼树中,跳出循环重新选择新结点
if (HuffTreeNode[j].parent != -1)
continue;
if (min1>HuffTreeNode[j].count)
{
pt1 = j;
min1 = HuffTreeNode[j].count;
continue;
}
}
//上面已经取出最小的,把它做为哈夫曼树的左结点,设置好相关信息
HuffTreeNode[i].count = HuffTreeNode[pt1].count;
HuffTreeNode[pt1].parent = i;//找到第i个结点的左孩子
HuffTreeNode[i].lch = pt1;//计算左分支权值大小
min1 = 0x7FFFFFFF;
for (j = 0; j
{
if (HuffTreeNode[j].parent != -1)
continue;
if (min1>HuffTreeNode[j].count)
{
pt1 = j;
min1 = HuffTreeNode[j].count;
continue;
}
}
//第i个结点的权值为左右孩子权值之和
HuffTreeNode[i].count += HuffTreeNode[pt1].count;
HuffTreeNode[i].rch = pt1;//设置第i个结点的右孩子
HuffTreeNode[pt1].parent = i;//设置第i个结点右孩子的父结点信息
}
printf("字节下标\t字节值\t权值\t父亲\t左孩子\t右孩子\t\n");
for (int k = 0; k
{
if (HuffTreeNode[k].count != 0)
printf("%d\t\t%02x\t%d\t%d\t%d\t%d\t\n", k, HuffTreeNode[k].b, HuffTreeNode[k].count, HuffTreeNode[k].parent, HuffTreeNode[k].lch, HuffTreeNode[k].rch);
}
return n;
}
//Huffman树编码
void BHuffmanTree(HuffNode HuffTreeNode[], int n)
{
int i;
for (i = 0; i
{
int f = i;
HuffTreeNode[i].bits[0] = 0;//ASCII码为0的字符,即为\0结束符
while (HuffTreeNode[f].parent != -1)//若没到根结点
{
int j = f;
f = HuffTreeNode[f].parent;//判断当前结点与父结点的关系
if (HuffTreeNode[f].lch == j)
{
j = strlen(HuffTreeNode[i].bits);
//拷贝,留出位置放当前的编码
//j+1意味拷贝时把\0复制,memmove不出现重叠部分被覆盖
memmove(HuffTreeNode[i].bits + 1, HuffTreeNode[i].bits, j + i);
//依次存储连接“0”“1”编码
HuffTreeNode[i].bits[0] = '0';//左分支记为0
}
else //置右分支编码1
{
j = strlen(HuffTreeNode[i].bits);
memmove(HuffTreeNode[i].bits + 1, HuffTreeNode[i].bits, j + 1);
HuffTreeNode[i].bits[0] = '1';
}
}
}
printf("字节下标\t字节值\t权值\t父亲\t左孩子\t右孩子\t哈夫曼编码\n");
for (int k = 0; k<256; k++)
{
int m = 0;
if (HuffTreeNode[k].count != 0)
{
printf("%d\t\t%02x\t%d\t%d\t%d\t%d\t", k, HuffTreeNode[k].b, HuffTreeNode[k].count, HuffTreeNode[k].parent, HuffTreeNode[k].lch, HuffTreeNode[k].rch);
while (HuffTreeNode[k].lch == -1 && HuffTreeNode[k].bits[m] != 0)
{
printf("%c", HuffTreeNode[k].bits[m]);
m++;
}
printf("\n");
}
}
}