任务描述
相关知识
编程要求
测试说明
任务描述
本关任务:编写一个能计算huffman编码的程序。
相关知识
在上一关中,我们已经能构造一个哈夫曼树。那么从根结点到每个叶子结点的路径上,如果是左孩子则标注1,右孩子则标注0,于是从根结点到叶子结点可以得到一个01串,即是叶子结点的哈夫曼编码。 已知叶子结点的定义是
struct bnode {
int lchild, rchild, parent;
double weight;
int length; //到根结点的路径长度
int pos; //结点在表中位置 char code[MAX]; //存放编码;
};
把每个叶子结点i的huffman编码填写到HT[i].code中。
编程要求
首先把第一关通过的部分代码void SelectTwoMin(bnode HT[],int len, int &min1, int &min2)复制过来,以完成哈夫曼树的构造。
再编写代码void MakeCode(bnode HT[],int i, char code[]),将哈夫曼编码填到叶子结点中。注意makecode是一个递归程序,它从根结点开始填写所有结点的编码(从根结点到内结点i的路径上的01串也记录在内结点的HT[i].code中)。
测试说明
平台会根据你给出的哈夫曼编码长度计算WPL.
先输入叶子结点个数n, 再输入n个权值。
测试输入:5 1 2 3 4 5
预期输出:33.00
开始你的任务吧,祝你成功!
#include "HuffmanTree.h"
#include <string.h>
#include <stdio.h>
#include<stdlib.h>
int CreateHuffman(bnode HT[], double w[], int n){
int i,min1,min2;
double sum;
for (i=0;i<n;i++) { //建立n个单结点的树
HT[i].lchild=-1;
HT[i].rchild=-1;
HT[i].parent=-1; // parent=-1表示是树根
HT[i].weight=w[i];
HT[i].pos=i;
}
for (i=n;i<2*n-1;i++){
SelectTwoMin(HT, i, min1, min2); //选择树根权值最小的两棵树
HT[min1].parent=i;
HT[min2].parent=i;
HT[i].lchild=min1;
HT[i].rchild=min2;
HT[i].parent=-1;
HT[i].weight= HT[min1].weight+ HT[min2].weight;
HT[i].pos=i; }
}
void SelectTwoMin(bnode HT[],int len, int &min1, int &min2){
//begin
int i;
int minnum = 0;
for (int i = 0; i < len; i++)
{
if (HT[i].parent == -1)
{
minnum = i;
break;
}
}
for (int i = 1; i < len; i++)
{
if (HT[i].parent == -1)
{
if (HT[i].weight < HT[minnum].weight)
minnum = i;
}
}
min1 = minnum;
minnum = 0;
for (int i = 1; i < len; i++)
{
if (HT[i].parent == -1 && i != min1)
{
minnum = i;
break;
}
}
for (int i = 1; i < len; i++)
{
if (i != min1 && HT[i].parent == -1)
{
if (HT[i].weight < HT[minnum].weight)
minnum = i;
}
}
min2 = minnum;
//end
}
void MakeCode(bnode HT[],int root, char code[]){
//从根结点开始填写每个结点的编码。
//begin
int n=(root+2)/2;
code[n-1]='\0';
for(int i=0;i<n;i++)
{
int start=n-1;
int c=i;
int p=HT[i].parent;
while(p!=-1&&p!=2*n-1)
{
start--;
if(HT[p].lchild==c)
code[start]='1';
else code[start]='0';
c=p;
p=HT[p].parent;
}
strcpy(HT[i].code,&code[start]);
}
}
注意:以上方法在创建哈夫曼树时需稍稍修改 如下