第2关:输出哈夫曼编码

任务描述
相关知识
编程要求
测试说明
任务描述
本关任务:编写一个能计算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]);
}
}

注意:以上方法在创建哈夫曼树时需稍稍修改   如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值